C 在运行多个进程时使用共享内存的信号量

C 在运行多个进程时使用共享内存的信号量,c,concurrency,semaphore,shared-memory,C,Concurrency,Semaphore,Shared Memory,我正在学习一些涉及信号量的简单生产者/消费者示例,但很难向自己解释为什么我会得到一个特定的结果(因为我是C语言的高手) 当我运行以下生产者的两个并发进程时,两个进程都会挂起并且永远不会完成: #include <stdio.h> #include <sys/types.h> #include <semaphore.h> #include <sys/stat.h> #include <fcntl.h> #include <stdli

我正在学习一些涉及信号量的简单生产者/消费者示例,但很难向自己解释为什么我会得到一个特定的结果(因为我是C语言的高手)

当我运行以下生产者的两个并发进程时,两个进程都会挂起并且永远不会完成:

#include <stdio.h>
#include <sys/types.h>
#include <semaphore.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/shm.h>

#define BUFF_SIZE 20

typedef struct {
    char buffer[BUFF_SIZE];
    int nextIn;
    int nextOut;
} shared_data;

shared_data *shm, *s;

char sem_name1[] = "mutex";
char sem_name2[] = "empty_slots";
char sem_name3[] = "full_slots";

sem_t *empty_slots;
sem_t *full_slots;
sem_t *mutex;

void Put(char item)
{
    sem_wait(empty_slots);
    sem_wait(mutex);
    s->buffer[s->nextIn] = item;
    s->nextIn = (s->nextIn + 1) % BUFF_SIZE;
    sem_post(mutex);
    printf("Producing %c ... with pid = %d\n", item, getpid());
    sem_post(full_slots);
}

void Producer()
{
    int i;
    for(i = 0; i < 10; i++)
    {
        sleep(rand()%3);
        Put((char)('A'+ i % 26));
    }
}

void main()
{
    //Create and initialize the semaphores
    mutex=sem_open(sem_name1, O_CREAT,0644, 1);
    full_slots=sem_open(sem_name3, O_CREAT,0644, 0);
    empty_slots=sem_open(sem_name2, O_CREAT,0644, 10);

    //Create a key for the segment
    key_t key;
    key = 1234;

    //create the segment
    int shmid;
    if ((shmid = shmget(key, sizeof(shared_data), IPC_CREAT |0666)) <0)
    {
        perror("Shmget");
        exit(1);
    }

    //attach to the segment
    if ((shm = (shared_data *) shmat(shmid, NULL, 0))==(shared_data *) -1)
    {
        perror("Shmat");
        exit(1);
    }

    s=shm;
    s->nextIn = 0;

    Producer();

    //detach from the segment
    shmdt((void *) shm);
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义BUFF_大小20
类型定义结构{
字符缓冲区[BUFF_SIZE];
int nextIn;
int nextOut;
}共享数据;
共享_数据*shm,*s;
字符sem_name1[]=“互斥”;
char sem_name2[]=“空插槽”;
char sem_name3[]=“满插槽”;
sem_t*空槽;
sem_t*满槽;
sem_t*互斥体;
作废放置(字符项)
{
sem_等待(空_插槽);
sem_wait(互斥);
s->buffer[s->nextIn]=物料;
s->nextIn=(s->nextIn+1)%BUFF\u大小;
sem_post(互斥);
printf(“生成%c…且pid=%d\n”,项,getpid());
sem_柱(全槽);
}
无效生产者()
{
int i;
对于(i=0;i<10;i++)
{
睡眠(rand()%3);
Put((char)('A'+i%26));
}
}
void main()
{
//创建并初始化信号量
互斥量=sem_open(sem_name1,O_CREAT,0644,1);
满槽=打开(sem\U名称3,O\U创建,0644,0);
空插槽=打开(sem\U名称2,O\U创建,0644,10);
//为段创建关键点
钥匙(t)钥匙;;
密钥=1234;
//创建段
int shmid;
如果((shmid=shmget(key,sizeof(shared_data),IPC_CREAT | 0666))nextIn=0;
生产者();
//从段中分离
shmdt((void*)shm);
}
第一个和第二个过程的输出分别为:

有人能帮我理解为什么会发生这种情况(即为什么这些过程永远不会结束)?我是否造成了僵局?为什么?为什么?我完全被难住了


谢谢!

当使用命名信号量时,第一个字符应该是“/”。您必须始终检查
sem\u
函数的返回。事实上,它们可能由于不同的原因而失败,请查看手册页面如何捕获不同的情况。通常,信号量的用法是(创建后),sem\u wait(信号量名称)..…sem_post(信号量名称)。当实现信号量生产者/消费者序列时,1)只需要一个信号量。2) 当一个进程通过sem_wait递减一个信号量值时,它需要通过sem_post递增同一个信号量,发布的代码没有正确处理这些信号量。因此,当某个信号量值达到0时(从sem_wait开始),那么对该信号量的任何进一步sem_wait都将永远等待,直到其他进程对该信号量执行sem_post。计数信号量(如代码试图实现的信号量)将只让生产者执行sem_post。当然,需要有一个消费者只执行sem_等待。如果将计数限制在某个最大值,则在执行sem_post之前,生产商应执行sem_getvalue,以确保在生产另一个项目之前有空间容纳另一个项目item@user3629249是的,我知道我需要使用
sem\u post
。我有一个与之关联的使用者文件,当我运行并发使用者进程和这些生产者进程时,一切都运行得很好。然而,我的问题是为什么运行两个生产者(不执行任何消费者)会挂起显示的输出。正如你所说,我认为这是因为我的
空\u插槽
信号量被初始化为
10
并无限期地等待,但我将其增加到
20
,但仍然得到相同的结果。我想我把自己搞糊涂了!