第二个线程在第一个完成之前不会运行

时间:2013-04-18 17:10:40

标签: c pthreads

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

我删除了其他一些部分,但那是我遇到麻烦的地方(头部早先在主要部分初始化)。如果我按原样运行代码,则打印出“创建生成器线程”。然后不断打印出“等待消费者”。直到我按 Ctrl + C 并停止它。此外,如果我删除生成器线程顶部的循环,它将遍历其所有迭代,然后调用使用者线程。无论出于何种原因,它都是串行而不是并行运行。

3 个答案:

答案 0 :(得分:6)

更改

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

是:

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

(对消费者来说相同)


而且:你应该总是测试系统调用的结果!


和^ 2:例如,使用互斥锁保护对consumer_thread_alive的并发访问!


和^ 3:线程函数ougth具有以下形式:

void * thread_func(void *);

因此,生成器的线程函数的实现可能如下所示:

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

但要注意,因为您传递同一 struct Node 的实例的引用同时线程 ,因此线程函数内的并发访问也需要受到保护(参见上面的和^ 2 )。

答案 1 :(得分: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;
}

答案 2 :(得分:0)

pthread_create(//producer's)
pthread_join(//producer's)
pthread_create(//consumer's)
pthread_join(//consumer's)

这个命令可行。

编辑:当我尝试实现同样的事情时,这有效。试试吧。