开发者

How to quit simple Producer-Consumer problem

I am trying to work out a simple producer-consumer program. I have this code:

//global variable g_lastImage is declared as:
volatile int g_lastImage = 0;

void producer(void) {
    int i = 0;
    while (1) {     
        sem_wait(&g_shm->PSem);
        printf("I:%d\n",i);
        if (i == 5) {
            g_lastImage = 1;
            printf("It's time to say goodbye!\n");
            sem_post(&g_shm->ChSem);
            return;
        }
        printf("producing\n"); 
        i++;
        sem_post(&g_shm->ChSem);
    }
}


void consumer(void) {
    while (1) {
        sem_wait(&g_shm->ChSem);
        if (g_lastImage) {
            printf("Bye!\n");
            return;
        }
        printf("consuming\n");
        sem_post(&g_shm->PSem);
    }
}

int main() {
    alloc(); /*allocates shared memory and two semaphores, 
                  ChSem on initial counter value 0 and PSem on value 1*/
    int processes = 1; //let's start with one process only just for now
    int id = 0, i = 0, status;

    for (i = 0; i < processes; i++) {
        id = fork();
        if (id < 0) {
          perror ("error\n");
          exit(1);
        } else if (id == 0) {
          consumer();
          printf("child exits\n");
          exit(0);
        }
    }
    producer();

    for (i = 0; i < processes; ++i) {
        wait(&status);
    }
    return 1;
}

Unfortunately this code ends with deadlock. I have this output:

I:0
producing
consuming
I:1
producing
consuming
I:2
producing
consuming
I:3
producing
consuming
I:4
producing
consuming
I:5
It's time to say goodbye!
consuming
//deadlock - nothing written 

Please notice that "Bye!" is not written. On the other hand extra "consuming" is. What is wrong with this solution? Using global variable开发者_运维问答 for detecting the end is not ok? Can't figure it out...

Thank you for any ideas.

EDIT: Acording to your advices I changed the allocation of local variable to volatile and added the '\n' but the problem persists.


You have to share your flag too, this works as you expect :

#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/mman.h>

struct Shared
{
    sem_t PSem ;
    sem_t ChSem ;
    int g_lastImage ;
} * g_shm ;

void producer(void) {
    int i = 0;
    while (1) {     
        sem_wait(&g_shm->PSem);
        printf("I:%d\n",i);
        if (i == 5) {
            g_shm->g_lastImage = 1;
            printf("It's time to say goodbye!\n");
            sem_post(&g_shm->ChSem);
            return;
        }
        printf("producing\n"); 
        i++;
        sem_post(&g_shm->ChSem);
    }
}


void consumer(void) {
    while (1) {
        sem_wait(&g_shm->ChSem);
        if (g_shm->g_lastImage) {
            printf("Bye!\n");
            return;
        }
        printf("consuming\n");
        sem_post(&g_shm->PSem);
    }
}

int main()
{
    g_shm = mmap( NULL , sizeof( struct Shared ) , PROT_READ | PROT_WRITE , MAP_SHARED | MAP_ANONYMOUS , -1 , 0 );
    sem_init( & g_shm->PSem , 1 , 1 );
    sem_init( & g_shm->ChSem , 1 , 0 );
    g_shm->g_lastImage = 0 ;

    int processes = 1;
    int id = 0, i = 0, status;

    for (i = 0; i < processes; i++)
    {
        id = fork();
        if (id < 0) {
          perror ("error\n");
          exit(1);
        } else if (id == 0) {
          consumer();
          printf("child exits\n");
          exit(0);
        }
    }
    producer();

    for (i = 0; i < processes; ++i)
    {
        wait(&status);
    }
    return 1;
}


volatile won't help you here, because you fork your processes. This will result in a copy of g_lastImage and therefore the parentprocess, which calls producer() will change its own value of g_lastImage, whereas the childprocess (who gets its own copy of that variable at fork) will always have g_lastImage == 0 and therefore you end up in a deadlock. You might just insert the allocation of g_lastImage into the allocation of your semaphores as well, as it seems that you allocated them correctly to have them in poth processes ;)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜