关于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
semaphoreis 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

