首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >sem_open在程序第二次运行时失败,尽管sem_close调用成功

sem_open在程序第二次运行时失败,尽管sem_close调用成功
EN

Stack Overflow用户
提问于 2017-09-18 19:12:22
回答 1查看 3.8K关注 0票数 2

我使用sem_opensem_close创建和销毁信号量,因为在OS上不受欢迎

当我第一次运行我的程序时,信号量起了预期的作用。在我的程序结束时,我调用sem_close,它没有错误地返回。

但是,如果我再次运行该程序,sem_open将在EEXIST中失败。

O_CREAT和O_EXCL都是在oflag中指定的,但是具有此名称的信号量已经存在。

sem_close函数不仅在第一次运行期间成功返回,而且男子档案建议在进程终止时关闭信号量,不管是:

所有打开的命名信号量在进程终止时都会自动关闭。

所以我弄不明白为什么信号量会持续存在。

MCVE

代码语言:javascript
运行
复制
// 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;
}

第一次和第二次运行输出

代码语言:javascript
运行
复制
$ ./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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-09-18 19:12:22

我需要同时使用sem_closesem_unlink。这是在OS上的init中提到的,但我忽略了意义。这个答案帮助详细说明何时使用每个函数。总结:

sem_close只释放信号量使用的资源。关闭的信号量仍然存在,可以重新打开。

当所有进程停止使用信号量时,sem_unlink标记要销毁的信号量。

@JohnBollinger在评论中补充道,

如果您只需要在一个程序的一个运行期间使用信号量,那么您应该考虑在创建它之后(通过sem_unlink())立即解除它的链接。然后,您可以继续使用它,直到关闭它,但它不会阻止程序的其他实例使用相同的信号量名称。此外,由于打开的信号量是关闭的,但在程序退出时不会自动断开链接,这将保护您在程序崩溃之前不让信号量挂起。

示例解

代码语言:javascript
运行
复制
// 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;
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46286579

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档