【问题标题】:Product-consumer with semaphores and forks使用信号量和分叉的产品消费者
【发布时间】:2014-05-06 02:38:02
【问题描述】:

不知道为什么消费者要做所有的工作?

我用一个由 10 个整数组成的数组为 prodcut-consumer 创建了一个信号量,该数组用名称填充,它以 1 和 0(二进制)返回。即使生产者取消信号量,也会调用消费者。

为什么会这样?

这是代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <semaphore.h>
#include <fcntl.h>
#define SIZE 10
#define KEY 1234
int *Memory;
int i, j;
sem_t *sem;
char *name = "Hello";
int main(int argc, const char *argv[])
{
    int shmid;
    if ((shmid = shmget(KEY, sizeof(int) * SIZE, IPC_CREAT | S_IRWXU)) < 0)
    {
        perror("Error while creating shmget");
        return 1;
    }
    pid_t pid;
    sem = sem_open(name, O_CREAT, S_IRUSR | S_IWUSR, 1);
    if ((pid = fork()) != 0)
    {
        if ((shmid = shmget(KEY, sizeof(int) * SIZE, S_IRWXU)) < 0)
        {
            perror("error in shmget");
            return 1;
        }
        Memory = (int *)shmat(shmid, NULL, 0);
        if (Memory == NULL)
        {
            perror("error in shmat");
            return 1;
        }
        for (i = 0; i < 10; i++)
        {
            sem_wait(sem);
            Memory[j] = i;
            printf("Produced %i in box %i\n", i + 1, i + 1);
            sem_post(sem);
            sleep(1);
        }
        int status;
        wait(&status);
        sem_unlink(name);
        sem_destroy(sem);
        struct shmid_ds shmid_ds1;
        if (shmctl(shmid, IPC_RMID, &shmid_ds1) < 0)
        {
            perror(
                "Error in the father while executing shmctl when it was "
                "elimnating the segment of shared memory");
        }
    }
    else
    {
        if ((shmid = shmget(KEY, sizeof(int) * SIZE, S_IRWXU)) < 0)
        {
            perror("error in the producer with the shmget");
            return 1;
        }
        Memory = (int *)shmat(shmid, NULL, 0);
        if (Memory == NULL)
        {
            perror("error in the producer with the  shmat");
            return 1;
        }
        for (i = 0; i < 10; i++)
        {
            sem_wait(sem);
            Memory[i] = -1;
            printf("Consume and now it is %i in box %i\n", Memory[i], i + 1);
            sem_post(sem);
        }
    }
    return 0;
}

输出是:

Produced 1 in box 1
Consume and now it is -1 in box 1
Consume and now it is -1 in box 2
Consume and now it is -1 in box 3
Consume and now it is -1 in box 4
Consume and now it is -1 in box 5
Consume and now it is -1 in box 6
Consume and now it is -1 in box 7
Consume and now it is -1 in box 8
Consume and now it is -1 in box 9
Consume and now it is -1 in box 10
Produced 2 in box 2
Produced 3 in box 3
Produced 4 in box 4
Produced 5 in box 5
Produced 6 in box 6
Produced 7 in box 7
Produced 8 in box 8
Produced 9 in box 9
Produced 10 in box 10

【问题讨论】:

    标签: c fork semaphore shared-memory producer-consumer


    【解决方案1】:
    #include <pthread.h>
    #include <stdio.h>
    #include <semaphore.h>
    const int max = 5;
    int arr[5], f = 0, r = -1;
    sem_t s1, s2, sm;
    void* eprod(void* pv)
    {
        int i, x;
        printf("Producer Welcome\n");
        // sleep(10);
        while (1)
        {
            x = rand() % 100;
            printf("producer going to add:%d\n", x);
            sem_wait(&s2);
            sem_wait(&sm);
            // down s2 //buffer may be full
            // lock sm
            r = (r + 1) % max;
            arr[r] = x;
            sem_post(&sm);
            sem_post(&s1);
            sleep(10);
        }
        // unlock sm
        // up s1
    }
    void* econs(void* pv)
    {
        int i, x;
        printf("Consumer Welcome\n");
        while (1)
        {
            sem_wait(&s1);
            sem_wait(&sm);
            // down s1
            // lock sm
            x = arr[f];
            f = (f + 1) % max;
            printf("Consumer removed element:%d\n", x);
            sem_post(&sm);
            sem_post(&s2);
            // unlock sm
            // up s2
            // sleep(5);
        }
    }
    int main()
    {
        pthread_t pt1, pt2;
        sem_init(&s1, 0, 0);    // 3rd Parameter ival=1
        sem_init(&s2, 0, max);  // 3rd Parameter ival=1
        sem_init(&sm, 0, 1);    // 3rd Parameter ival=1
        pthread_create(&pt1, NULL, eprod, (void*)0);
        pthread_create(&pt2, NULL, econs, (void*)1);
        printf("Main Thread is Running\n");
        pthread_join(pt1, NULL);
        pthread_join(pt2, NULL);
        printf("Main -- - - Thanks..!\n");
        return 0;
    }
    

    希望这会有所帮助..

    【讨论】:

    • 谢谢@user2485710 我已经使用线程解决了这个问题,并且工作完美。但是您知道我如何使用信号量和分叉解决消费者生产问题吗?
    • @user3606231 右边的名字是发帖用户的名字,我只是编辑了它以修复缩进。
    【解决方案2】:

    您的输出与您的程序代码一致。 您的两个进程都使用信号量来访问共享内存块,因此它们通过互斥方式工作,即在任何给定时间只允许其中一个进程使用Memory[] 数组。

    但是您的程序中没有任何东西可以进一步限制进程的行为,因此消费者可以在生产者不做任何事情的情况下继续进行。

    您需要在您的程序中引入更多的簿记功能来处理Memory[] 数组中的保留/空闲槽,以及另外两个信号量来同步生产者和消费者的进度。查看问题的任何标准解决方案,例如http://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem#Using_semaphores

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-22
      • 2013-11-19
      相关资源
      最近更新 更多