You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于POSIX线程与信号量的学生线程创建及状态打印参数传递问题求助

POSIX线程与信号量的学生线程创建及状态打印参数传递问题求助

Hey there! Let's break down the issues with your printInfo() parameter passing and get that student status output working exactly like your example.

First, let's fix the printInfo() parameter problem

Right now your startEvent() function calls printInfo() with no arguments, but the function is defined to expect struct student *s (the full array of students) and int num (total number of students). The problem is each thread only gets a pointer to a single student—we need to pass the entire student array and total count to the thread so it can pass them to printInfo().

Step 1: Create a thread argument struct

We need to wrap all the data each thread needs into one struct, since pthread_create only accepts a single void* argument:

// Add this struct before your startEvent function
struct thread_args {
    struct student *all_students;  // Pointer to the full student array
    int total_students;            // Total number of students
    struct student *current_student; // Pointer to the current student being created
    int student_idx;               // Index of the current student in the array
};

Step 2: Pass the argument struct when creating threads

In your main() function, modify the thread creation loop to allocate and populate this struct for each thread:

for(i=0;i<NUM_THREADS;i++){
    struct thread_args *args = malloc(sizeof(struct thread_args));
    if (!args) {
        perror("Failed to allocate thread args");
        return EXIT_FAILURE;
    }
    args->all_students = Students;
    args->total_students = NUM_THREADS;
    args->current_student = &Students[i];
    args->student_idx = i;

    if( pthread_create(&Students[i].thread,NULL,&startEvent,args) != 0 ){
        perror("Error trying to create a thread\n");
        free(args); // Clean up if thread creation fails
    }
}

Step 3: Update startEvent() to use the argument struct

Now modify the thread function to unpack the arguments and call printInfo() correctly:

void * startEvent(void * args){
    struct thread_args *thread_args = (struct thread_args*)args;
    struct student *current_student = thread_args->current_student;
    struct student *all_students = thread_args->all_students;
    int total_students = thread_args->total_students;

    pthread_mutex_lock(&mutex);
    
    // Assign a creation order number (matches your example's Student 1, 2, etc.)
    int creation_num = ++count;
    current_student->creation_order = creation_num;
    printf("\nStudent %d (%s) created.\n", creation_num, getScience(current_student->department));

    sleep(1);

    // Now pass the correct parameters to printInfo
    printInfo(all_students, total_students);

    pthread_mutex_unlock(&mutex);

    free(args); // Don't forget to free the allocated argument struct
    return NULL;
}

Fix the printInfo() function logic

Your current printInfo() has a bug where it uses s->position instead of accessing each student in the array. Let's fix that, plus update it to print the creation order number from your example:

First, add a creation_order field to your student struct to track the Student 1/2/3 number:

struct student{
    pthread_t thread;
    int am;
    int time;
    enum place position;
    enum science department;
    int creation_order; // New field to track the student's creation sequence
};

Then fix the printInfo() function:

void printInfo(struct student * s,int num){

    printf("\nStop A: ");
    for(int i=0;i<num;i++){
        if(s[i].position == stopA){ // Use s[i] to access the i-th student
            printf("[%d , %s ] ", s[i].creation_order, getScience(s[i].department));
        }
    }
    printf("\nBus: ");
    for(int i=0;i<num;i++){
        if(s[i].position == Bus){
            printf("[%d , %s ] ", s[i].creation_order, getScience(s[i].department));
        }
    }
    printf("\nUniversity: ");
    for(int i=0;i<num;i++){
        if(s[i].position == University){
            printf("[%d , %s ] ", s[i].creation_order, getScience(s[i].department));
        }
    }
    printf("\nStop B: ");
    for(int i=0;i<num;i++){
        if(s[i].position == stopB){
            printf("[%d , %s ] ", s[i].creation_order, getScience(s[i].department));
        }
    }
    printf("\n");
}

Don't forget to implement the getScience() function

You mentioned this function exists, but just in case you haven't written it yet, here's a simple implementation:

const char* getScience(enum science dept) {
    switch(dept) {
        case Math: return "Math";
        case Physics: return "Physics";
        case Chemistry: return "Chemistry";
        case CSD: return "CSD";
        default: return "Unknown";
    }
}

Quick notes on other parts

  • Your semaphore is initialized but not used in the current code—if you plan to use it for synchronization later, make sure to integrate it properly.
  • The sleep(1) is just for demonstration; you might want to remove it or adjust it for your actual use case.

With these changes, each time a student thread is created, it will print the student's creation number and department, then call printInfo() with the full student array to display all students' current positions correctly.

备注:内容来源于stack exchange,提问作者mitsislav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 08:59:32