共享存储器和POSIX信号(Shared memory and POSIX semaphores)

2019-10-23 01:34发布

我在写C.简单的消费者 - 生产者方案这是工作的罚款,而我有1对生产者和消费者1。 但是,当我增加消费者的数量是演戏奇怪。

  1. 我开始生产者进程
  2. 生产者是生产
  3. 我开始消费过程
  4. 消费者在消费和生产者的生产
  5. 我开始消费过程中没有2
  6. 消费过程中NO2从来没有得到一个元素
  7. 当我等消费者开始NO3,NO4 ......以及,同样的情况发生

第二个问题:

  1. 产生器产生的最大元件
  2. 消费者消费的所有元素,但生产者不继续生产了

我不知道为什么它正在发生。

码:

制片人:

#include <semaphore.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <fcntl.h>
#include "common.h"

int memoryID;
struct wrapper *memory;
int rc;

void atexit_function() {
    rc = shmctl(memoryID, IPC_RMID, NULL);
    rc = shmdt(memory);
    sem_destroy(&memory->pmutex);
    sem_destroy(&memory->cmutex);
    sem_destroy(&memory->empty);
    sem_destroy(&memory->full);
}

int main(int argc, char **argv) {
    atexit(atexit_function);
    //creating key for shared memory
    srand(time(NULL));
    key_t sharedMemoryKey = ftok(".", MEMORY_KEY);
    if (sharedMemoryKey == -1) {
        perror("ftok():");
        exit(1);
    }

    memoryID = shmget(sharedMemoryKey, sizeof(struct wrapper), IPC_CREAT | 0600);
    if (memoryID == -1) {
        perror("shmget():");
        exit(1);
    }

    memory = shmat(memoryID, NULL, 0);
    if (memory == (void *) -1) {
        perror("shmat():");
        exit(1);
    }

    //initialization

    printf("Initializtaion !\n");
    memset(&memory->array, 0, sizeof(memory->array));
    sem_init(&memory->pmutex, 0, 1);
    sem_init(&memory->cmutex, 0, 1);
    sem_init(&memory->empty, 0, SIZE_OF_ARRAY);
    sem_init(&memory->full, 0, 0);
    memory->n = -1;

    if (memoryID == -1) {
        perror("shmget(): ");
        exit(1);
    }


    while(1)
    {
        int r = rand();
        sem_wait(&memory->empty);
        sem_wait(&memory->pmutex);
        memory->n++;
        (memory->array)[memory->n]=r;
        printf("Adding task\t Value:%d\tNumber of tasks waiting:%d \n",r,memory->n);
        usleep(10000);
        sem_post(&memory->pmutex);
        sem_post(&memory->full);
    }

}

消费者:

#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "common.h"
#include <sys/shm.h>

int memoryID;
struct wrapper *memory;
int check_prime(int a);
int main(int argc, char **argv) {
    srand(time(NULL));
    key_t sharedMemoryKey = ftok(".",MEMORY_KEY);
    if(sharedMemoryKey==-1)
    {
        perror("ftok():");
        exit(1);
    }
    memoryID=shmget(sharedMemoryKey,sizeof(struct wrapper),0);

    if(memoryID==-1)
    {
        perror("shmget(): ");
        exit(1);
    }

    memory = shmat(memoryID,NULL,0);
    if(memory== (void*)-1)
    {
        perror("shmat():");
        exit(1);
    }

    while(1)
    {
        sem_wait(&memory->full);
        sem_wait(&memory->cmutex);

        int n = memory->n;
        int temp = (memory->array)[n];
        printf("Removed item: %d\tPrime:%d\tNumer of tasks left:%d\n",
            temp, check_prime(temp),n);
        memory->n--;
        usleep(10000);

        sem_post(&memory->cmutex);
        sem_post(&memory->empty);
    }

}

COMMON.H:

#define MEMORY_KEY 12
#define SIZE_OF_ARRAY 10
struct wrapper
{
    int array[SIZE_OF_ARRAY];
    sem_t empty;
    sem_t pmutex;
    sem_t cmutex;
    sem_t full;
    int n;
};

Answer 1:

问题解决了。 我设置int sem_init(sem_t *sem, int pshared, unsigned int value); 我设置pshared值设置为0,但是:

  The pshared argument indicates whether this semaphore is to be shared between the threads of a process, or between processes. If pshared has the value 0, then the semaphore is shared between the threads of a process, and should be located at some address that is visible to all threads (eg, a global variable, or a variable allocated dynamically on the heap). If pshared is nonzero, then the semaphore is shared between processes, and should be located in a region of shared memory (see shm_open(3), mmap(2), and shmget(2)). (Since a child created by fork(2) inherits its parent's memory mappings, it can also access the semaphore.) Any process that can access the shared memory region can operate on the semaphore using sem_post(3), sem_wait(3), etc. 


文章来源: Shared memory and POSIX semaphores