2016-12-05 166 views
0

我有一個與生產者和消費者有關的問題。我有1個生產者和3個消費者。製作人出示我放在隊列中的信件,消費者拿着這封信。據認爲,當兩個消費者接受信件時,信件已經從隊列中移除,但是有一個選項,消費者A和消費者C不能接受同一封信(可能A會先寫信,那麼con。B將首先採用第二或con。B,然後con C(或A)秒,但當A和C在一起時不可能)。POSIX生產者 - 消費者

我寫了一個解決這個問題的代碼,但是現在我不能從函數中打印任何東西。

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
#include <semaphore.h> 
#include <unistd.h> 
#include "FIFO.h" 

#define semaphore sem_t 
#define MAX_SIZE _SIZE 
#define SLEEP 1 
#define true 1 

FIFO buff; 
semaphore full, empty, a_read, b_read, c_read, mutex; 

void randSleep(int max) { 
    double x = rand()/(double)RAND_MAX; 
    usleep((int)floor(x*max)); 
} 


void* producer_func() 
{ 
    char c='A'; 
    while(GetAmount(&buff)<MAX_SIZE) 
    { 
     sem_wait(&empty); 
     sem_wait(&mutex); 

     Push(&buff, c); 

     sem_post(&mutex); 
     sem_post(&full); 

     randSleep(SLEEP); 
    } 
    pthread_exit(NULL); 
} 

void* consumer_a_func() 
{ 
    char c; 
    long int first_met; 

    while(true) 
    { 
     sem_wait(&a_read); 
     sem_wait(&full); 

     if (sem_getvalue(&b_read,&first_met)) printf("Error with returning b_read value"); 
     sem_wait(&mutex); 

     if (first_met) 
     { 
      c = First(&buff); 
      sem_post(&mutex); 
     } 
     else 
     { 
      c = Pop(&buff); 
      sem_post(&mutex); 
      sem_post(&a_read); 
      sem_post(&b_read); 
      sem_post(&empty); 
     } 
     //printf("c value %s\n", c); 
     randSleep(SLEEP); 
    } 

    pthread_exit(NULL); 
} 

void* consumer_b_func() 
{ 
    char c; 
    long int first_met_a, first_met_c ; 

    while(true) 
    { 
     sem_wait(&b_read); 
     sem_wait(&full); 

     if (sem_getvalue(&a_read,&first_met_a)) printf("Error with returning a_read value"); 
     if (sem_getvalue(&c_read,&first_met_c)) printf("Error with returning c_read value"); 

     sem_wait(&mutex); 
     if (first_met_a && first_met_c) 
     { 
      c = First(&buff); 
      sem_post(&mutex); 
     } 
     else 
     { 
      c = Pop(&buff); 
      sem_post(&mutex); 
      sem_post(&b_read); 
      if (first_met_a) 
       sem_post(&c_read); 
      else 
       sem_post(&a_read); 
      sem_post(&empty); 
     } 
     //printf("c value %s\n", c); 
     randSleep(SLEEP); 
    } 

    pthread_exit(NULL); 
} 

void* consumer_c_func() 
{ 
    char c; 
    long int first_met; 

    while(true) 
    { 

     sem_wait(&c_read); 
     sem_wait(&full); 

     if (sem_getvalue(&b_read,&first_met)) printf("Error with returning b_read value"); 

     sem_wait(&mutex); 

     if (first_met) 
     { 
      c = First(&buff); 
      sem_post(&mutex); 
     } 
     else 
     { 
      c = Pop(&buff); 
      sem_post(&mutex); 
      sem_post(&c_read); 
      sem_post(&b_read); 
      sem_post(&empty); 
     } 
     printf("c value %s\n", c); 
     randSleep(SLEEP); 
    } 

    pthread_exit(NULL); 
} 

int main() 
{ 
    Init(&buff); 
    sem_init(&empty, 0, MAX_SIZE); 
    sem_init(&full, 0, 0); 
    sem_init(&a_read, 0, 1); 
    sem_init(&b_read, 0, 1); 
    sem_init(&c_read, 0, 1); 
    sem_init(&mutex, 0, 1); 

    pthread_t producer, consumer_a, consumer_b, consumer_c; 

    pthread_create(&producer, NULL, producer_func, NULL); 
    printf("All right\n"); 
    pthread_create(&consumer_a, NULL, consumer_a_func, NULL); 
    printf("All right\n"); 
    pthread_create(&consumer_b, NULL, consumer_b_func, NULL); 
    printf("All right\n"); 
    pthread_create(&consumer_c, NULL, consumer_c_func, NULL); 
    printf("All right\n"); 

    pthread_join(&producer, (void**)NULL); 
    pthread_join(&consumer_a, (void**)NULL); 
    pthread_join(&consumer_b, (void**)NULL); 
    pthread_join(&consumer_c, (void**)NULL); 

} 

文件FIFO.hFIFO.c

誤差看起來像

在_IO_vfprintf_internal(S = 0x7ffff78ac620 < _IO_2_1_stdout_>,格式=,AP = AP @條目= 0x7ffff6acfe58)在vfprintf.c: 1632()

或分段錯誤(核心轉儲)

但有時這種代碼運行正常,但沒有任何的printf的我在生產者 - 消費者功能寫道

+0

伴侶,如果你想得到任何答案,你必須將你的問題減少到簡單,簡短和教學的代碼。閱讀堆棧溢出的推薦做法。 –

+0

對不起,我的「小」代碼,但我不知道哪個部分工作錯了=( – koshachok

+0

請問,如果你的問題只是關於printf,請爲未來的用戶更改你的問題的標題 –

回答

1
//printf("c value %s\n", c); 

c是一個字符,打印它,你應該使用

printf("c value %c\n", c); 

你可以試試使用-Wformat進行編譯,所以如果在printf調用中對變量使用無效格式,則會發生警告。

+0

一般來說,我會建議使用['-Wall'](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wall-323)(gcc鏈接),其中包括你的' (具有諷刺意味的是,'-Wall'並不是所有可能的警告。) – e0k

+0

或者強迫自己真正學習C,用'-Wall -Wextra -pedantic'進行編譯,並且不接受任何代碼,直到它編譯時沒有任何警告。(除了'-Wall'外加'-Wextra -pedantic'給你幾乎所有可能的警告) –

+0

@ DavidC.Rankin:至少加上'-Wconversion'一般來說,最好是靜音警告(例如* *好理解的**演員)比之後想知道發生了什麼 – Olaf