2016-06-02 3 views
1

학교에서 맡은 일 중 하나는이 코드를 수정하는 것입니다. 생산자와 소비자 스레드는 지역 변수를 교대로 증가시키고 인쇄해야하지만 어떻게 수정해야하는지 잘 모릅니다.C : 생산자/소비자

생산자와 소비자 스레드가 무한히이를 수행 할 수 있어야합니다. 그러나 실행 파일을 시작하면 임의로 중지됩니다.

누군가이 동작을 설명 할 수 있다면 좋을 것입니다.

#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; 
} 

출력이 예 같아야 :

$ ./event 
producer: wait... 
consumer: wait... 
producer: PRODUCE 0... 
producer: wait... 
consumer: CONSUME 0... 
consumer: wait... 
producer: PRODUCE 1... 
producer: wait... 
consumer: CONSUME 1... 
consumer: wait... 
producer: PRODUCE 2... 
producer: wait... 
consumer: CONSUME 2... 
consumer: wait... 
.... 
+0

[this] (https://stackoverflow.com/questions/29455170/c-threads-to-print-sequence-of-numbers-with-even-and-odd-number-printing-threa/29455846#) 29455846) – user3386109

+0

힌트 : 소비자 스레드가 먼저 'cond_consumed'CV 신호를 보내기 전에 'sleep (1)'해야하는 이유는 무엇입니까? –

+0

힌트 2 : 각 스레드를 차단할 수있는 곳은 어디입니까? –

답변

3

발생할 수있는 문제 thread_B 전에 thread_A 신호가 pthread_cond_wait 문에 도달한다는 것이다 여기

코드이다. Thread_B는 신호를 보지 않고 대신 기다리고 있습니다. specs 따르면

: 현재 COND 차단에는 스레드가없는 경우

가 pthread_cond_signal() 및 어떤 pthread_cond_broadcast는() 함수는 아무런 효과가 없다.

이로 인해 교착 상태가 발생합니다. 이는 교착 상태입니다.

2

투어 코드를 실행했습니다. 교착 상태가 발생합니다. 두 스레드가 조건 변수에서 대기 중입니다. 다음은 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 [email protected]@GLIBC_2.3.2() from /lib64/libpthread.so.0 
2 Thread 0x7f78bf3b3700 (LWP 8126) 0x00000032b2e0b5bc in [email protected]@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 [email protected]@GLIBC_2.3.2() 
from /lib64/libpthread.so.0 
(gdb) bt 
#0 0x00000032b2e0b5bc in [email protected]@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 [email protected]@GLIBC_2.3.2() 
from /lib64/libpthread.so.0 
(gdb) bt 
#0 0x00000032b2e0b5bc in [email protected]@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 [email protected]@GLIBC_2.3.2() 
from /lib64/libpthread.so.0 
(gdb) bt 
#0 0x00000032b2e0b5bc in [email protected]@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: 
[email protected]: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. 

조건 변수를 올바르게 사용하거나 세마포어를 사용하십시오. 세마포어는 생산자 소비자 문제에 사용하기 쉽습니다.