0

我正在尝试实现生产者/消费者类型的东西,其中生产者线程从字符串中抓取字符并将它们放入循环链表队列(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;
}

我剪掉了其他一些部分,但这就是我遇到麻烦的地方(head 在 main 中早些时候被初始化)。如果我按原样运行代码,它会打印出“创建生产者线程”。然后不断打印出“Waiting on Consumer”。直到我按下Ctrl+C并停止它。此外,如果我删除生产者线程顶部的循环,它会运行所有迭代,然后调用消费者线程。无论出于何种原因,它都以串行方式而不是并行方式运行。

4

3 回答 3

6

改变

pthread_create(&produce, NULL, (void *) producer(&head), NULL );

成为:

pthread_create(&produce, NULL, producer, &head);

(消费者也一样)


并且:您应该始终测试系统调用的结果!


consumer_thread_aliveAnd^2:例如使用互斥锁来保护并发访问!


并且^3:线程函数应该具有以下形式:

void * thread_func(void *);

所以你对生产者线程函数的实现可能会像这样开始:

void * producer(void * pvhead)
{
  struct Node * head = pvhead;
  ...

但请注意,当您向两个线程传递对同一实例的引用时,线程函数内部对它的并发访问也需要受到保护(参见上面的And^2 )。struct Node

于 2013-04-18T17:24:05.580 回答
1
   int pthread_create(pthread_t *restrict thread, const pthread_attr_t *restrict attr,
          void *(*start_routine)(void*), void *restrict arg);

上面的语法pthread_create#include <pthread.h>头文件中声明。

所以你必须改变以下工作

   pthread_create(&produce, NULL, producer, (void *)&head);

完整的工作代码:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void * producer(void * );
void * consumer(void * );
struct node{
int x;
};
struct node head;
int consumer_thread_alive;
void * producer(void * head)
{
    printf("producer\n");
    pthread_exit(NULL);    
}
void * consumer(void * head)
{
    consumer_thread_alive = 1;
    printf("consumer\n");
    pthread_exit(NULL);
 }

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, producer, (void*)&head );
    printf("Creating consumer thread.\n");
    pthread_create(&consume, NULL, consumer, (void*)&head );
    pthread_join(produce,NULL);
    pthread_join(consume,NULL);
    return 1;
}
于 2013-04-18T17:46:57.683 回答
0
pthread_create(//producer's)
pthread_join(//producer's)
pthread_create(//consumer's)
pthread_join(//consumer's)

这个命令会起作用。

编辑:当我确实尝试实现相同的事情时,这很有效。试一试。

于 2013-04-18T18:03:50.603 回答