POSIX生产者 - 消费者

时间:2016-12-05 00:08:42

标签: c posix semaphore producer-consumer

我遇到与生产者和消费者有关的问题。我有1个生产者和3个消费者。制片人出示我放入队列的信件,消费者会收到这封信。当2个消费者接受它时,认为已经从队列中删除了字母,但是有一个选项,消费者A和消费者C不能接受相同的字母(con .A可能会先写字母,然后con.B先取第二个或先取con B,然后取con C(或A)秒,但A和C合在一起时不可能。

我写了一个解决这个问题的代码,但现在我无法从函数中打印出来。

#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&lt; _IO_2_1_stdout_&gt;,format =,ap = ap @ entry = 0x7ffff6acfe58)at vfprintf.c:1632()

或分段错误(核心转储)

但有时这段代码运行正常,但没有我在生产者 - 消费者函数中编写的任何printf

1 个答案:

答案 0 :(得分:1)

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

c是一个字母,打印它应该使用

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

您可以尝试使用-Wformat进行编译,因此如果在printf调用中对变量使用无效格式,则会发生警告。