我正在尝试实现一个生产者/消费者类型的东西,其中生产者线程从字符串中抓取字符并将它们放入循环链表列表(5个节点大)中,并且消费者线程读入字符并将它们打印到屏幕.两个线程在到达新行字符时停止.我遇到的问题是,在生产者线程终止之前,消费者线程永远不会启动.
int consumer_thread_alive;
...
void * producer(struct Node * head)
{
while (consumer_thread_alive == 0)
{
printf("Waiting on consumer.");
}
...
}
void * consumer(struct Node * head)
{
consumer_thread_alive = 1;
...
}
...
int main(int argc, char *argv[])
{
...
consumer_thread_alive = 0;
pthread_t produce;
pthread_t consume;
printf("Creating producer thread.\n");
pthread_create(&produce, NULL, (void *) producer(&head), NULL );
printf("Creating consumer thread.\n");
pthread_create(&consume, NULL, (void *) consumer(&head), NULL );
pthread_join(produce,NULL);
pthread_join(consume,NULL);
return 1;
}
Run Code Online (Sandbox Code Playgroud)
我删除了其他一些部分,但那是我遇到麻烦的地方(头部早先在主要部分初始化).如果我按原样运行代码,则打印出"创建生成器线程".然后不断打印出"等待消费者".直到我按下Ctrl+C并停止它.此外,如果我删除生成器线程顶部的循环,它将遍历其所有迭代,然后调用使用者线程.无论出于何种原因,它都是串行而不是并行运行.
更改
pthread_create(&produce, NULL, (void *) producer(&head), NULL );
Run Code Online (Sandbox Code Playgroud)
成为:
pthread_create(&produce, NULL, producer, &head);
Run Code Online (Sandbox Code Playgroud)
(对消费者来说也一样)
而且:你应该总是测试系统调用的结果!
和^ 2:consumer_thread_alive
例如,使用互斥锁保护并发访问!
和^ 3:线程函数ougth具有以下形式:
void * thread_func(void *);
Run Code Online (Sandbox Code Playgroud)
因此,生成器的线程函数的实现可能如下所示:
void * producer(void * pvhead)
{
struct Node * head = pvhead;
...
Run Code Online (Sandbox Code Playgroud)
但请注意,当您向两个线程传递对同一实例的引用时,因此也需要保护线程函数内对它的并发访问(请参阅 上面的^ ^ 2).struct Node