共享内存和POSIX信号灯 [英] Shared memory and POSIX semaphores

查看:80
本文介绍了共享内存和POSIX信号灯的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用C语言编写了简单的消费者-生产者程序.当我有1个生产者和1个消费者时,它运行良好.但是,当我增加消费者数量时,这表现得很奇怪.

I wrote simple consumer-producer program in C. It is working fine while I have 1 producer and 1 consumer. But it is acting strange when I increase number of consumers.

  1. 我开始制作过程
  2. 生产者正在生产
  3. 我开始消费过程
  4. 消费者正在消费,生产者正在生产
  5. 我开始2号消费者程序
  6. 第2个消费过程从不获取元素
  7. 当我开始使用第3号,第4号...等等的消费者时,也会发生同样的情况

第二个问题:

  1. 生产者生产了最多的元素
  2. 消费者消耗了所有元素,但生产者不再继续生产

我不知道为什么会这样.

I have no idea why it is happening.

代码:

制作人:

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

推荐答案

问题已解决. 我正在设置int sem_init(sem_t *sem, int pshared, unsigned int value); 我将pshared值设置为0,但是:

Problem solved. I was setting int sem_init(sem_t *sem, int pshared, unsigned int value); I was setting pshared value to 0 but:

   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 (e.g.,  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.

这篇关于共享内存和POSIX信号灯的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆