请参阅下面的伪代码。 代码注释应该解释我的问题。 我是 C 中的 pthreads 和链表的新手,所以我有点跳入深渊。 我只需要在thread_work
函数中打印出str
的值。 顺序代码位很好,但是当每个线程完成其工作时,它无法打印出str
的值。
// linked list definition
struct linked_list {
char *str;
struct linked_list *next;
};
// linked list initiation
struct linked_list *root;
struct linked_list *next_info;
root = malloc( sizeof( struct linked_list ) );
// main code
some loop {
next_node->str = str;
printf( "%sn", next_node ); // PRINTS FINE
pthread_t thread;
rc = pthread_create( &thread, NULL, thread_work, (void *) &next_node );
next_node->next = malloc( sizeof( struct linked_list ) );
next_node = next_node->next;
}
// code executed by each thread
void *thread_work( void *thread_arg ) {
struct linked_list *ll;
ll = ( struct linked_list * )thread_arg;
printf( "%sn", ll->str ); // PRINTS SOME MESS (��E#)
}
在我的实际代码中,linked_list
struct
还有几个成员。
非常感谢。
指针类型不匹配:您传递的是指向列表节点的指针,但在thread_work
内部将其视为指向节点的指针。删除调用 pthread_create
中next_node
前的 & 符号,或按如下方式更改thread_work
:
void *thread_work( void *thread_arg ) {
struct linked_list **llp, *ll;
llp = ( struct linked_list ** )thread_arg;
ll = *llp;
printf( "%sn", ll->str ); // PRINTS SOME GOOD STUFF
}
如果printf( "%sn", next_node )
工作正常,next_node是一个指针,因此你不会指向pthread_create()中的指针。next_node的定义会很好;)
试试rc = pthread_create( &thread, NULL, thread_work, (void *) next_node );
这段代码很糟糕:
// main code
some loop {
next_node->str = str;
printf( "%sn", next_node ); // PRINTS FINE
pthread_t thread;
rc = pthread_create( &thread, NULL, thread_work, (void *) &next_node );
next_node->next = malloc( sizeof( struct linked_list ) );
next_node = next_node->next;
}
这里的问题是您正在传递一个指向变量的指针,该变量的值在调用 pthread_create
后立即更改。由于操作系统将进程克隆到新线程中需要一些时间,因此实际thread_work
可能会(并且在大多数情况下)在执行next_node = next_node->next;
语句后启动并选择错误的next_node
值。您应该传递 next_node
的值,而不是它的地址:
// main code
some loop {
next_node->str = str;
printf( "%sn", next_node->str ); // PRINTS FINE
pthread_t thread;
rc = pthread_create( &thread, NULL, thread_work, (void *) next_node );
// Store this thread handle somewhere safe to be able to join the thread later on
next_node->next = malloc( sizeof( struct linked_list ) );
next_node->next->str = next_node->next->next = NULL; // Always a good idea
next_node = next_node->next;
}