我使用sem_open和sem_close创建和销毁信号量,因为在OS上不受欢迎。
当我第一次运行我的程序时,信号量起了预期的作用。在我的程序结束时,我调用sem_close,它没有错误地返回。
但是,如果我再次运行该程序,sem_open将在EEXIST中失败。
O_CREAT和O_EXCL都是在oflag中指定的,但是具有此名称的信号量已经存在。
sem_close函数不仅在第一次运行期间成功返回,而且男子档案建议在进程终止时关闭信号量,不管是:
所有打开的命名信号量在进程终止时都会自动关闭。
所以我弄不明白为什么信号量会持续存在。
MCVE
// file: pc.cc
#include <semaphore.h>
#include <pthread.h>
#include <cstdio>
#include <cstdlib>
#include <errno.h>
int main(int argc, char *argv[])
{
errno = 0;
sem_t *semaphore = sem_open("/sem3", O_CREAT | O_EXCL, 0, 0);
if (semaphore == SEM_FAILED) {
int err1 = errno;
fprintf(stderr, "sem_open() failed. errno:%d\n", err1);
if (EEXIST == err1)
fprintf(stderr, "EEXIST : Both O_CREAT and O_EXCL were specified in oflag, but a semaphore with this name already exists. \n");
}
errno = 0;
if(sem_close(semaphore) == -1){
int err2 = errno;
fprintf(stderr, "sem_close() failed. errno:%d\n", err2);
if( EINVAL == err2)
fprintf(stderr, "EINVAL : sem is not a valid semaphore.");
}
return 0;
}第一次和第二次运行输出
$ ./output_test
$ ./output_test
sem_open() failed. errno:17
EEXIST : Both O_CREAT and O_EXCL were specified in oflag, but a semaphore with this name already exists.
sem_close() failed. errno:9发布于 2017-09-18 19:12:22
我需要同时使用sem_close和sem_unlink。这是在OS上的init中提到的,但我忽略了意义。这个答案帮助详细说明何时使用每个函数。总结:
sem_close只释放信号量使用的资源。关闭的信号量仍然存在,可以重新打开。
当所有进程停止使用信号量时,sem_unlink标记要销毁的信号量。
@JohnBollinger在评论中补充道,
如果您只需要在一个程序的一个运行期间使用信号量,那么您应该考虑在创建它之后(通过sem_unlink())立即解除它的链接。然后,您可以继续使用它,直到关闭它,但它不会阻止程序的其他实例使用相同的信号量名称。此外,由于打开的信号量是关闭的,但在程序退出时不会自动断开链接,这将保护您在程序崩溃之前不让信号量挂起。
示例解
// file: pc.cc
#include <semaphore.h>
#include <pthread.h>
#include <cstdio>
#include <cstdlib>
#include <errno.h>
int main(int argc, char *argv[])
{
errno = 0;
sem_t *semaphore = sem_open("/sem5", O_CREAT | O_EXCL, 0, 0);
sem_unlink("/sem5"); //Unlink to ensure semaphore is destroyed if program crashes
if (semaphore == SEM_FAILED) {
int err1 = errno;
fprintf(stderr, "sem_open() failed. errno:%d\n", err1);
if (EEXIST == err1)
fprintf(stderr, "EEXIST : Both O_CREAT and O_EXCL were specified in oflag, but a semaphore with this name already exists. \n");
}
//The semaphore will be closed when the program exits, but can also close it explicitly.
errno = 0;
if(sem_close(semaphore) == -1){
int err2 = errno;
fprintf(stderr, "sem_close() failed. errno:%d\n", err2);
if( EINVAL == err2)
fprintf(stderr, "EINVAL : sem is not a valid semaphore.");
}
return 0;
}https://stackoverflow.com/questions/46286579
复制相似问题