Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 共享内存和POSIX信号量_C_Concurrency_Posix_Ipc - Fatal编程技术网

C 共享内存和POSIX信号量

C 共享内存和POSIX信号量,c,concurrency,posix,ipc,C,Concurrency,Posix,Ipc,我用C写了一个简单的消费者-制作人程序。当我有一个制作人和一个消费者时,它工作得很好。但当我增加消费者数量时,我的行为很奇怪 我开始制作过程 制片人正在制作 我启动消费者流程 消费者在消费,生产者在生产 我启动消费者流程2 使用者进程2从未获得元素 当我开始使用3号、4号消费者时。。。以此类推,同样的情况也会发生 第二个问题: 生产者生产了最多的元素 消费者消费所有元素,但生产者不再继续生产 我不知道为什么会这样 代码: 制作人: #include <semaphore.h> #in

我用C写了一个简单的消费者-制作人程序。当我有一个制作人和一个消费者时,它工作得很好。但当我增加消费者数量时,我的行为很奇怪

  • 我开始制作过程
  • 制片人正在制作
  • 我启动消费者流程
  • 消费者在消费,生产者在生产
  • 我启动消费者流程2
  • 使用者进程2从未获得元素
  • 当我开始使用3号、4号消费者时。。。以此类推,同样的情况也会发生
  • 第二个问题:

  • 生产者生产了最多的元素
  • 消费者消费所有元素,但生产者不再继续生产
  • 我不知道为什么会这样

    代码:

    制作人:

    #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);
        }
    
    }
    
    问题解决了。 我正在设置
    intsem\u init(sem\u t*sem,int pshared,unsigned int value)
    我将
    pshared
    值设置为0,但:


    我认为你必须把时间留给其他的过程去做sem。在sem发布后,睡你的while 1。不幸的是,这无助于发布的代码看起来不必要的复杂。似乎不需要任何信号量。数据需要一个互斥锁、一个计数器和一个数组。当没有对象/int可供处理时,使用者需要睡眠一段时间。当阵列已满时,生产者需要睡眠一段时间。我还建议,为了避免旧数据得不到及时处理,数组应被视为一个循环列表,带有一个头和尾指针
    #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);
        }
    
    }
    
    #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;
    };
    
       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.