首页 > 解决方案 > 如何在 C 中的生产者/消费者问题中使用信号量作为共享变量(共享内存)

问题描述

我一直在尝试在生产者/消费者问题中使用信号量,但我不知道如何在共享内存中声明信号量和互斥锁并在两个进程中使用它们。我当前的程序无法正常工作,但我将它们附在此处。请给我建议,并在此先感谢您。

生产者.c

#include "protocol.h"

// producer Code
static const char name[] = "sem";

void producer(struct ShmData *shmData, sem_t *sem) {
    
    for(int i = 0 ; i < 8; i++) {
        sleep(1);
        sem_post(sem);
        // If mutex is 1 and buffer is not full, then it is
        // possible to produce
        if ((shmData->mutex == 1) && (shmData->empty != 0)) {
            // Producer code starts here
            // Decrease mutex value by 1
            shmData->mutex = (shmData->mutex)-1; // mutex--

            // Decrease the number of buffer by 1
            shmData->full = (shmData->full) + 1; //full++
            shmData->empty = (shmData->empty) - 1; //empty--
          
            // Item produced
            shmData->x = (shmData->x) + 1; //x++
            printf("\nProducer produces item %d", shmData->x);
          
            // Increase mutex value by 1
            shmData->mutex = (shmData->mutex) + 1; //mutex++

            // Producer code ends here
        }
    }
}

int main()
{
    sem_unlink(name);
    sem_t *sem = sem_open(name, O_CREAT|O_EXCL, S_IRUSR|S_IWUSR, 0);
    if( sem == SEM_FAILED ) {
      err(EXIT_FAILURE, "sem_open");
    }

    int fd = shm_open(NAME, O_CREAT | O_EXCL | O_RDWR, 0600); 
    if (fd < 0) {
        perror("shm_open() producer error"); 
        close(fd); 
        shm_unlink(NAME); 
        return EXIT_FAILURE; 
    }

    ftruncate(fd, SIZE); 
    struct ShmData *shmData = mmap(0, sizeof(*shmData), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 

    shmData->mutex = 1; // mutual exclusion
    shmData->full  = 0; 
    shmData->empty = BUFFER;
    shmData->x     = 0; // Item number

    pthread_t th[THREAD_NUM];
    for (int i = 0; i < THREAD_NUM; i++) {
        if (pthread_create(&th[i], NULL, &producer, shmData) != 0) {
            perror("Failed to create thread");
        }
    }
    for (int i = 0; i < THREAD_NUM; i++) {
        if (pthread_join(th[i], NULL) != 0) {
            perror("Failed to join thread");
        }
    }
    
    munmap(shmData, SIZE); 
    close(fd); 
    return EXIT_SUCCESS; 
}

消费者.c

/* https://www.geeksforgeeks.org/producer-consumer-problem-in-c/ */

#include "protocol.h"
  
// consumer Code 
void consumer(struct ShmData *shmData) {
    
    for(int i = 0 ; i < 8; i++) {
        sleep(2); 
        // If mutex is 1 and buffer is not empty, then it is
        // possible to consume

        if ((shmData->mutex == 1) && (shmData->full != 0)) {
            // consumer code starts here
            // Decrease mutex value by 1
            shmData->mutex = (shmData->mutex) - 1; // mutex--
          
            // Increase the number of empty
            // slots by 1
            shmData->full = (shmData->full) - 1; // full--;
            shmData->empty = (shmData->empty) + 1; // empty++;

            printf("\nConsumer consumes item %d", shmData->x);
            shmData->x = (shmData->x) - 1; // x--;
          
            // Increase mutex value by 1
            shmData->mutex = (shmData->mutex) + 1; // mutex++;
            // consumer code ends here
        }
        sleep(1);
    }
}

int main()
{
    sleep(1);
    int fd = shm_open(NAME, O_EXCL | O_RDWR, 0600); 
    if (fd < 0) {
        perror("shm_open() consumer error"); 
        close(fd); 
        shm_unlink(NAME); 
        return EXIT_FAILURE; 
    }

    ftruncate(fd, SIZE); 
    struct ShmData *shmData = mmap(0, sizeof(*shmData), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 

    pthread_t th[THREAD_NUM];
    for (int i = 0; i < THREAD_NUM; i++) {
        if (pthread_create(&th[i], NULL, &consumer, shmData) != 0) {
            perror("Failed to create thread");
        }
    }
    for (int i = 0; i < THREAD_NUM; i++) {
        if (pthread_join(th[i], NULL) != 0) {
            perror("Failed to join thread");
        }
    }

    munmap(shmData, SIZE); 
    close(fd); 
    shm_unlink(NAME); 
    return EXIT_SUCCESS; 
}

协议.h

#ifndef PROTOCOL_H
#define PROTOCOL_H

#define NAME "/pcp-sharemem"
#define NUM 4
#define SIZE (NUM * sizeof(int))
#define BUFFER 2
#define THREAD_NUM 1

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <pthread.h>
#include <err.h> 
#include <semaphore.h>

struct ShmData {
    int mutex; 
    int full; 
    int empty; 
    int x; 
};

#endif /* PROTOCOL_H */

标签: csemaphoreshared-memoryproducer-consumer

解决方案


推荐阅读