C 创建多个信号量时出错

C 创建多个信号量时出错,c,semaphore,C,Semaphore,老师给了我们这个作业,她已经给了我们一个创建信号量的过程,还有其他一些过程。我可以用这个过程创建一个信号量,但只能创建一个,当尝试创建第二个信号量时,它会显示一个错误。我真的试图寻找解决方案,但我甚至找不到类似过程的代码。在“sem_create”过程中是否有我应该更改的内容 代码如下: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h>

老师给了我们这个作业,她已经给了我们一个创建信号量的过程,还有其他一些过程。我可以用这个过程创建一个信号量,但只能创建一个,当尝试创建第二个信号量时,它会显示一个错误。我真的试图寻找解决方案,但我甚至找不到类似过程的代码。在“sem_create”过程中是否有我应该更改的内容

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/sem.h>

int sem_create(key_t CLEF,int initval) {
    union semun {
        int val;
        struct semid_ds *buf;
        ushort *array;
    } arg_ctl;
    int semid;
    semid = semget(ftok("Disjktra.h<votre login>",CLEF),
                   1, IPC_CREAT|IPC_EXCL|0666);
    if (semid == -1)
        return -1;
    arg_ctl.val = initval; // sth is missing here
    if (semctl(semid, 0, SETVAL, arg_ctl) == -1)
        return -1;
    return semid;
}


/////////////////////////////////
/////////////////////////////////

void main() {
    int i, CLE=33, S1=0, S2=0;

    if ((S1 = sem_create(CLE,0)) == -1) {
        perror("error in creating semaphore 1");
        exit(-1);
    }

    if ((S2 = sem_create(CLE,0)) == -1) {
        perror("error in creating semaphore 2");
        exit(-1);
    }
}
根据

如果semflg同时指定了
IPC_create
IPC_EXCL
,并且密钥的信号量集已经存在,那么
semget()
将失败,errno设置为
EEXIST

这似乎很清楚。您的
sem\u create
函数调用
semget
来创建一个“Disjktra.h”信号量,但前提是该信号量不存在。你不能在同一个程序中做两次

编辑:另请注意,从ftok(3)手册页:

指定的路径必须指定调用进程可以访问的现有文件,否则调用将失败

我相信,如果您检查
ftok
的结果,您会发现它无法为任一信号量生成有效密钥:

key_t semkey = ftok("Disjktra.h<votre login>",CLEF);
if (semkey < 0) {
    perror("error creating key");
    return -1;
}
key\u t semkey=ftok(“Disjktra.h”,谱号);
如果(semkey<0){
perror(“创建密钥时出错”);
返回-1;
}
基于此,我建议使用一个真正的文件作为
ftok
的路径名,或者完全放弃
ftok
,每次使用
semget(IPC\u private,…)
创建一个私有信号量


另一方面,您的代码很难理解其格式。请考虑清理您的代码,这样在发布问题时阅读更容易。

< P> <强>信号量排他性< /强> BR> 第一次:
semget()返回信号量的ID。还有要看的支票 如果该值大于0,则结果为真 正在执行打印ID的printf()
第二次
下一次返回的b semget()值是
小于0表示信号量alread存在。 结果执行了perror()函数


原因是:文件存在

@Mat如何传递不同的ID?如何设置这个IPC_EXCL?@Mat我试图在Main中向sem_create的参数传递一个不同的键,但仍然给出相同的错误:/
ftok
的文档似乎说更改CLE参数应该会产生不同的键,但我同意尝试更改路径名也是有意义的。@qwrrty我同时更改了CLE参数和该路径名,但仍然给出了相同的错误:/我尝试了第二个选项(在没有EPC_EXCL的情况下调用semget),但在使用不同的键调用sem_create时它却不起作用。如果这个EPC_EXCL仅仅阻止我们创建另一个信号量,那么为什么会有这个EPC_EXCL呢?很抱歉代码太乱了,但老实说,我不太了解它,无法组织它..当程序创建一个信号量时,用同一个键创建两次信号量通常是错误的。使用
IPC_EXCL
可以防止程序员意外地使用同一个键创建两个信号量。如果我是你,我会关心为什么更改信号量键似乎不能解决问题,我会更仔细地调查,试图了解那里发生了什么。谢谢,我会考虑你所说的。由于时间有限,我可能会尝试只使用一个信号量来完成我的工作。@MoheDreamy我可能已经找到了根本的问题-请查看修改后的答案。谢谢,我终于使用这段代码使用不同的路径创建了两个信号量:shmkey=ftok(“/dev/null”,5)//shmid=shmget(shmkey,sizeof(int),0644 | IPC|u CREAT);shmid=semget(shmkey,1,IPC|u CREAT | IPC|u EXCL | 0666);
key_t semkey = ftok("Disjktra.h<votre login>",CLEF);
if (semkey < 0) {
    perror("error creating key");
    return -1;
}