显然,当打开现有信号量时,O_CREAT
和O_EXCL
不是必需的。
O_CREAT
创建新信号量时需要。
O_EXCL
仅当与 进行 OR 运算时才有意义O_CREAT
,指定如果具有给定名称的信号量已存在,则返回错误。
可以通过包含 <fcntl.h> 来获取标志值的定义
但我没有找到任何标志fcntl.h这告诉我如何打开现有的信号量。
答案1
考虑以下示例:
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
const char* const sem_name = "lock.sem";
if (argc == 1) {
sem_t* const sem = sem_open(sem_name, O_CREAT, 0644, 0);
if (sem == NULL) {
perror("sem_open");
return 1;
}
sem_wait(sem); // Will block
sem_close(sem);
sem_unlink(sem_name);
} else {
sem_t* const sem = sem_open(sem_name, 0);
if (sem == NULL) {
perror("sem_open");
return 1;
}
sem_post(sem); // Will unblock the other process
sem_close(sem);
}
return 0;
}
我使用参数计数来控制程序的行为。
如果我不提供任何参数(即,何时argc == 1
),则程序将打开信号量,如果信号量尚不存在则创建它;它将信号量的值初始化为0
。然后它对对象执行 asem_wait()
操作sem
。由于信号量被初始化为0
,这会导致进程阻塞。
现在,如果我运行同一程序的第二个实例,但这次使用任何非零数量的参数(即,when argc != 1
),则程序将打开信号量,但如果信号量尚不存在,则不会创建它。请注意,我传递0
了参数oflag
(即,我没有传递任何标志)。然后程序执行 a 操作sem_post()
,将信号量从0
增加到1
。这将解除第一个进程的阻塞。两个进程都将关闭对信号量的引用并终止。
如果我正确理解你的问题,第二种情况就是你正在寻找的。
如果我尝试先运行第二种情况(即,当第一种情况没有正在运行的实例时),那么我会得到:
$ ./a.out foo
sem_open: No such file or directory
这是从调用来的,perror()
因为具有给定名称的信号量不存在。