在 Linux 中信号量(Semaphore)可以认为是一个不可以小于零的计数器,用来在不同的进程或者线程中同步行为。

1. 用法

信号量可以认为是一个计数器,所以他的操作非常简单,主要操作只有两个,一个是用于增加值的 sem_post,另一个是用于减少值的 sem_wait。如果当前信号量的值为 0,调用 sem_wait 将会杜塞直到信号量的值大于0。

信号量可以分为两类,一类为有名信号量还有一类是无名信号量。

1.1 有名信号量

有名信号量通常用于不同进程之间来做同步,在使用前需要先调用 sem_open 来创建一个信号量,实际生成的文件会被放在 /dev/shm 下面。在成功创建之后就可以使用 sem_postsem_wait 做加减操作了,在不需要使用之后可以使用 sem_unlink 来删除对应的信号量,

#include <semaphore.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    sem_t* sem_test;

    sem_test = sem_open("test_sem", O_CREAT, 0644, 0);
    if (sem_test == SEM_FAILED)
    {
        perror("Failed to open semphore for test");
        return -1;
    }
    printf("Success to open semphore for test");

    sem_post(sem_test);
    sem_wait(sem_test);

    sem_unlink("test_sem");

    return 0;
}

1.2 无名信号量

无名信号量通常用于不同线程之间来做同步,不需要是使用 sem_open 来创建但是在使用之前需要使用 sem_init 做初始化。初始化之后的操作就和有名信号量是一样的啦。

#include <semaphore.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    sem_t* sem_test;
    int rv;

    rv = sem_init(sem_test, 0, 0);
    if(rv != 0)
    {
        perror("Failed to init semphore for test");
        return -1;
    }

    printf("Success to init semphore for test");

    sem_post(sem_test);
    sem_wait(sem_test);

    return 0;
}

参考