2016-02-24 62 views
1

我想使用POSIX命名信号来确保我的可执行程序只有一个实例可以运行。但我遇到了麻烦;信号量的值始终为0,因此它总是阻塞。命名为POSIX信号量的问题

#include <semaphore.h> /* required for semaphores */ 
#include <stdio.h> 
#include <unistd.h>  /* usleep */ 
#include <fcntl.h>  // O_EXCL 
#include <assert.h> 
#include <stdlib.h>  /* exit, EXIT_FAILURE */ 


int main(int argc, char *argv[]) 
{ 
    int ret; 
    int i; 
    sem_t* semaphore; 

    semaphore = sem_open("/mysemaphore", O_EXCL, 0777 /*0644*/, 2); 
    printf("sem_open returned %p at line %u\n", semaphore, __LINE__); 

    // if it exists, open with "open", and parameters will be ignored (therefore given as 0) 
    if(!semaphore) 
    { 
    semaphore = sem_open("/mysemaphore", O_CREAT, 0, 0); 
    printf("sem_open returned %p at line %u\n", semaphore, __LINE__); 
    } 

    // either of the above calls should have given us a valid semaphore 
    assert(semaphore); 

    // read its value time and again 
    ret = sem_getvalue(semaphore, &i); 
    printf("sem_getvalue returned %i at line %u, value is %i\n", ret, __LINE__, i); 

// .... 

输出:

sem_open returned 0x8003a4e0 at line 36 
sem_getvalue returned 0 at line 50, value is 0 

平台:Cygwin的1.7.33-2

内置用这个命令:

gcc Main.c -o Main -lpthread 

帮助非常感谢!

+0

信号灯将在开始时的0值是否有任何地方的任何代码,实际上增加(调用sem_post( ))在你的信号量? – nos

回答

1

使用sem_post(semaphore)增加,sem_wait(semaphore)减少。

此外,使用O_CREAT时,模式和价值应指定到一些有用的东西:

semaphore = sem_open("/mysemaphore", O_CREAT, 0777, 0); 
+0

非常感谢您回复我的请求。但是,我不明白你的意思是“模式和值应该指定为有用的东西”:我将值设置为1或2,因为这是我想要的,但它似乎没有效果。 “价值”和“模式”的正确值是什么?无论如何,如果值为0,那么设置值的目的是什么? – FreeSpirit64

+0

针对上述情况,根据sem_open()规范,“如果指定了O_CREAT,并且具有给定名称的信号量已经存在,则模式和值将被忽略。” (我从[链接](http://man7.org/linux/man-pages/man3/sem_open.3.html)复制了此声明) – FreeSpirit64

+0

我可以确认使用sem_post()我可以增加信号量的值。它没有回答上面的问题,但它使我能够向前迈进一点。我现在可以看到的是,当我在程序结束时执行以下操作:'code'(sem_close(semaphore); sem_unlink(“/ mysemaphore”);)并再次运行该程序时,信号量仍然存在,即意外。 – FreeSpirit64