0

I have a problem connected with producers and consumers. I have 1 producer and 3 consumers. Producer produce letters which i put in my queue, and consumers take this letters. It is considered that letter has been removed from the queue, when 2 of consumers took it, but there is an option, that consumer A and consumer C can't take the same letter(it's possible that con. A will take letter first, then con. B will take it second or con. B first, then con C(or A) second, but no possibility when A and C together).

I wrote a code solving this problem, but now I can't print enything from functions.

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

}

files FIFO.h, FIFO.c

error looks like

In _IO_vfprintf_internal (s=0x7ffff78ac620 <_IO_2_1_stdout_>, format=, ap=ap@entry=0x7ffff6acfe58) at vfprintf.c:1632 ()

Or segmentation fault(core dumped)

But sometimes this code runs correctly, but without any printf's which i wrote in producer-consumer functions

koshachok
  • 460
  • 5
  • 19

1 Answers1

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

c is a char, to print it you should use

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

You can try to compile with -Wformat, so warning will happend if you use invalid format for variables in the printf calls.

Felipe Lavratti
  • 2,887
  • 16
  • 34
  • In general, I would suggest using [`-Wall`](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wall-323) (link for gcc), which (among others) includes your `-Wformat`. (Ironically, `-Wall` is not all possible warnings.) – e0k Dec 05 '16 at 01:05
  • Or to force yourself to really learn C, compile with `-Wall -Wextra -pedantic` and do not accept any code until it compiles without any warnings. (adding `-Wextra -pedantic` in addition to `-Wall` gives you just about all possible warnings) – David C. Rankin Dec 05 '16 at 01:09
  • @DavidC.Rankin: Add `-Wconversion` at least. In general it is better to silence warnings (e.g. by **well-understood** casts) than later wonder what's going on. – too honest for this site Dec 05 '16 at 01:12
  • It was one of the mistakes, but now i found a big one in algorithm. – koshachok Dec 05 '16 at 01:17