0

我正在尝试在我的 Mac 上使用信号量,当我尝试关闭打开的信号量时它会引发错误。所有初始化都成功,但是当它试图关闭第二个信号量时,它返回了错误的文件描述符错误。

下面的代码是打开和关闭的包装器:

void init_sem(sem_t * s, char * sema_name, int value)
{
    if((s = sem_open(sema_name, O_CREAT, 0644, value)) == SEM_FAILED)
    {
        perror("sem_open");
        exit(1);
    }
    printf("init semaphore %s\n", sema_name);
}
void destroy_sem(sem_t * s, char * sema_name)
{
    printf("destroying, %s\n", sema_name);
    if (sem_close(s) == -1) {
        perror("sem_close");
        exit(EXIT_FAILURE);
    }

    if (sem_unlink(sema_name) == -1) {
        perror("sem_unlink");
        exit(EXIT_FAILURE);
    }
}

在 main.c 中

sem_t * s, *a, *b;
init_sem(s, "/cs", 0);
init_sem(a, "/ps", 0);
init_sem(b, "/bs", 0);
destroy_sem(s, "/cs");
destroy_sem(a, "/ps"); //got error here
destroy_sem(b, "/bs");

知道为什么它不起作用吗?

4

2 回答 2

1

您正在传入*s它成为局部变量的位置。init_sem当您为其赋值时,该值在返回时消失。然后,当您调用时destroy_sim,您会将未初始化的值传递给sem_close.

您需要返回从以下位置返回的值sem_open

sem_t * init_sem(char * sema_name, int value)
{
    sem_t * s;
    if((s = sem_open(sema_name, O_CREAT, 0644, value)) == SEM_FAILED)
    {
        perror("sem_open");
        exit(1);
    }
    printf("init semaphore %s\n", sema_name);
    return s;
}

然后像这样调用它:

s = init_sem("/cs", 0);
a = init_sem("/ps", 0);
b = init_sem("/bs", 0);
于 2013-02-12T21:43:19.503 回答
0

Gabe 的回答是正确的。

作为替代方案,您可以这样做:

void init_sem(sem_t ** s, char * sema_name, int value)
{
    if((*s = sem_open(sema_name, O_CREAT, 0644, value)) == SEM_FAILED)
    {
        perror("sem_open");
        exit(1);
    }
    printf("init semaphore %s\n", sema_name);
}
void destroy_sem(sem_t * s, char * sema_name)
{
    printf("destroying, %s\n", sema_name);
    if (sem_close(s) == -1) {
        perror("sem_close");
        exit(EXIT_FAILURE);
    }

    if (sem_unlink(sema_name) == -1) {
        perror("sem_unlink");
        exit(EXIT_FAILURE);
    }
}
int main (int argc, const char * argv[])
{
    sem_t * s, *a, *b;
    init_sem(&s, "/cs", 0);
    init_sem(&a, "/ps", 0);
    init_sem(&b, "/bs", 0);
    destroy_sem(s, "/cs");
    destroy_sem(a, "/ps");
    destroy_sem(b, "/bs");
}
于 2013-02-12T22:13:17.943 回答