C:生产者/消费者

C:生产者/消费者,c,pthreads,mutex,consumer,producer,C,Pthreads,Mutex,Consumer,Producer,我在学校的任务之一就是修复这个代码。生产者线程和消费者线程应该交替增加它们的局部变量并将其打印出来,但我不知道如何修复它 生产者和消费者线程应该可以无限期地执行此操作,但如果我启动可执行文件,它将任意停止 如果有人能解释我的这种行为那就太好了 代码如下: #include <sys/types.h> #include <stdio.h> #include <unistd.h> #include <pthread.h> static pthread

我在学校的任务之一就是修复这个代码。生产者线程和消费者线程应该交替增加它们的局部变量并将其打印出来,但我不知道如何修复它

生产者和消费者线程应该可以无限期地执行此操作,但如果我启动可执行文件,它将任意停止

如果有人能解释我的这种行为那就太好了

代码如下:

#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

static pthread_mutex_t mutex;
static pthread_cond_t cond_consumed = PTHREAD_COND_INITIALIZER;
static pthread_cond_t cond_produced = PTHREAD_COND_INITIALIZER;

static void *producer( void *arg )
{
        unsigned long count=0;

        while( 1 ) {
                printf("producer: wait...\n");
                pthread_mutex_lock( &mutex ); // enter critical section
                pthread_cond_wait( &cond_consumed, &mutex );
                printf("producer: PRODUCE %ld...\n", count++);
                pthread_cond_signal( &cond_produced );
                pthread_mutex_unlock( &mutex ); // leave critical section
        }
        return NULL;
}

static void *consumer( void *arg )
{
        unsigned long count=0; 

        sleep( 1 );
        pthread_cond_signal( &cond_consumed );
        while( 1 ) {
                printf("consumer: wait...\n");
                pthread_mutex_lock( &mutex );
                pthread_cond_wait( &cond_produced, &mutex );
                printf("consumer: CONSUME %ld...\n", count++);
                pthread_cond_signal( &cond_consumed );
                pthread_mutex_unlock( &mutex );
        }
        return NULL;
}

int main( int argc, char **argv, char **envp )
{
        pthread_t p1, p2;

        if (pthread_mutex_init( &mutex, NULL )) {
                perror("pthread_mutex_init");
                return -1;
        }

        pthread_create( &p2, NULL, consumer, NULL );
        pthread_create( &p1, NULL, producer, NULL );

        pthread_join( p1, NULL );
        pthread_join( p2, NULL );

        pthread_mutex_destroy( &mutex );
        return 0;
}

可能出现的问题是线程A在线程B到达
pthread\u cond\u wait
语句之前发出信号。线程B永远不会看到信号,而是一直等待它

根据报告:

如果cond上当前没有被阻止的线程,pthread_cond_signal()和pthread_cond_broadcast()函数将无效


这将导致死锁,这正是您所经历的

我已经执行了巡更代码。这导致了僵局。 两个线程都在等待条件变量。 下面是gdb跟踪

(gdb) bt
#0  0x00000032b2e0822d in pthread_join () from /lib64/libpthread.so.0
#1  0x0000000000400a1c in main ()
(gdb) info thread
 3 Thread 0x7f78bfdb4700 (LWP 8125)  0x00000032b2e0b5bc in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
 2 Thread 0x7f78bf3b3700 (LWP 8126)  0x00000032b2e0b5bc in  pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
 * 1 Thread 0x7f78bfdb6700 (LWP 8124)  0x00000032b2e0822d in pthread_join () from /lib64/libpthread.so.0
(gdb) thread 2
[Switching to thread 2 (Thread 0x7f78bf3b3700 (LWP 8126))]#0  0x00000032b2e0b5bc in pthread_cond_wait@@GLIBC_2.3.2 ()
from /lib64/libpthread.so.0
(gdb) bt
#0  0x00000032b2e0b5bc in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1  0x00000000004008eb in producer ()
#2  0x00000032b2e079d1 in start_thread () from /lib64/libpthread.so.0
#3  0x00000032b26e8b6d in clone () from /lib64/libc.so.6
(gdb) thread 2
[Switching to thread 2 (Thread 0x7f78bf3b3700 (LWP 8126))]#0  0x00000032b2e0b5bc in pthread_cond_wait@@GLIBC_2.3.2 ()
from /lib64/libpthread.so.0
(gdb) bt
#0  0x00000032b2e0b5bc in pthread_cond_wait@@GLIBC_2.3.2 () from  /lib64/libpthread.so.0
#1  0x00000000004008eb in producer ()
#2  0x00000032b2e079d1 in start_thread () from /lib64/libpthread.so.0
#3  0x00000032b26e8b6d in clone () from /lib64/libc.so.6
gdb) thread 3
[Switching to thread 3 (Thread 0x7f78bfdb4700 (LWP 8125))]#0  0x00000032b2e0b5bc in pthread_cond_wait@@GLIBC_2.3.2 ()
from /lib64/libpthread.so.0
(gdb) bt
#0  0x00000032b2e0b5bc in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1  0x000000000040096a in consumer ()
#2  0x00000032b2e079d1 in start_thread () from /lib64/libpthread.so.0
#3  0x00000032b26e8b6d in clone () from /lib64/libc.so.6

O/P:
smadala@gateway2:myExperiments$ ./a.out
producer: wait...
consumer: wait...
producer: PRODUCE 0...
producer: wait...
consumer: CONSUME 0...
consumer: wait...
producer: PRODUCE 1...
producer: wait...
consumer: CONSUME 1...
consumer: wait...
Blocked after this.

请正确使用条件变量或使用信号量。信号量在生产者-消费者问题中很容易使用。

尝试提示:消费者线程为什么需要
sleep(1)
在第一次发出
cond_cond_cond_cond
CV?提示2:每个线程在哪里可能被阻塞?仅我的2美分:条件变量被调用是有原因的,即,它们应该与某些数据的条件相联系,即它们为线程提供了一种基于数据值进行同步的方法。如果不仔细看代码,我可以看到条件变量只是自由浮动的,没有与数据的任何值/条件相关联,所以有些地方不对劲。我已经发布过很多次了,但我确实认为这是一个关于
pthreads
的很棒的教程,值得您花时间阅读全部内容:正如@yano所建议的,是的,您以错误的方式使用了条件变量。如果出现虚假信号,也会导致未定义的行为。您的代码正在经历死锁,这是由于在生产者到达条件等待之前,使用者发出了信号。我认为睡眠(1)只是为了避免上述问题。你可以做一件事,将睡眠时间间隔增加到30秒或1分钟。不过这也不会因为睡眠不足而导致死锁。这又是一个肮脏的补丁。您还可以通过使用2个计数信号量来简化实现。
(gdb) bt
#0  0x00000032b2e0822d in pthread_join () from /lib64/libpthread.so.0
#1  0x0000000000400a1c in main ()
(gdb) info thread
 3 Thread 0x7f78bfdb4700 (LWP 8125)  0x00000032b2e0b5bc in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
 2 Thread 0x7f78bf3b3700 (LWP 8126)  0x00000032b2e0b5bc in  pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
 * 1 Thread 0x7f78bfdb6700 (LWP 8124)  0x00000032b2e0822d in pthread_join () from /lib64/libpthread.so.0
(gdb) thread 2
[Switching to thread 2 (Thread 0x7f78bf3b3700 (LWP 8126))]#0  0x00000032b2e0b5bc in pthread_cond_wait@@GLIBC_2.3.2 ()
from /lib64/libpthread.so.0
(gdb) bt
#0  0x00000032b2e0b5bc in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1  0x00000000004008eb in producer ()
#2  0x00000032b2e079d1 in start_thread () from /lib64/libpthread.so.0
#3  0x00000032b26e8b6d in clone () from /lib64/libc.so.6
(gdb) thread 2
[Switching to thread 2 (Thread 0x7f78bf3b3700 (LWP 8126))]#0  0x00000032b2e0b5bc in pthread_cond_wait@@GLIBC_2.3.2 ()
from /lib64/libpthread.so.0
(gdb) bt
#0  0x00000032b2e0b5bc in pthread_cond_wait@@GLIBC_2.3.2 () from  /lib64/libpthread.so.0
#1  0x00000000004008eb in producer ()
#2  0x00000032b2e079d1 in start_thread () from /lib64/libpthread.so.0
#3  0x00000032b26e8b6d in clone () from /lib64/libc.so.6
gdb) thread 3
[Switching to thread 3 (Thread 0x7f78bfdb4700 (LWP 8125))]#0  0x00000032b2e0b5bc in pthread_cond_wait@@GLIBC_2.3.2 ()
from /lib64/libpthread.so.0
(gdb) bt
#0  0x00000032b2e0b5bc in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1  0x000000000040096a in consumer ()
#2  0x00000032b2e079d1 in start_thread () from /lib64/libpthread.so.0
#3  0x00000032b26e8b6d in clone () from /lib64/libc.so.6

O/P:
smadala@gateway2:myExperiments$ ./a.out
producer: wait...
consumer: wait...
producer: PRODUCE 0...
producer: wait...
consumer: CONSUME 0...
consumer: wait...
producer: PRODUCE 1...
producer: wait...
consumer: CONSUME 1...
consumer: wait...
Blocked after this.