2013-04-18 84 views
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; 
} 

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

+2

您不能使用简单的'int'变量同步线程。你必须使用适当的同步原语。 –

+3

对'pthread_create()'的调用是错误的。 – alk

+2

不要忽视你的编译器的警告,不要试图用cast来杀死警告。 (有时,演员阵容是正确的,但更多的时候,这是错误的解决方案,正在被诊断的问题。)请记住,编译器比你更了解C语言。 –

回答

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 Nice work ... –

+0

+1,用于彻底并仔细地解释此代码所带来的所有问题。耶为多线程! –

+0

@JonathanLeffler:谢谢...... :-) – alk

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); 

FULL工作代码:

#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; 
} 
0
pthread_create(//producer's) 
pthread_join(//producer's) 
pthread_create(//consumer's) 
pthread_join(//consumer's) 

这个命令会工作。

编辑:这工作时,我曾尝试实施相同的事情。试试吧。

+0

否;这是不明智的。生产者不会退出,直到消费者启动,因此加入第一个将不起作用。 –

相关问题