文章目录

与多进程程序一样,多线程程序也需要考虑同步问题。POSIX信号量、互斥锁与条件变量是3种专门用于线程同步的机制。

下面介绍POSIX信号量。

在Linux上,信号量API有两组,一组是System V IPC信号量;另一组是下面介绍的POSIX信号量。

关于信号量的原理不再赘述,常用的POSIX信号量的5个函数如下。

1
2
3
4
5
6
7
8
/*
引用方式: #include <semaphore.h>
sem: 指定操作的信号量
pshared: 指定信号量的类型; 0: 当前进程的局部信号量 || 非零: 信号量可在多进程间共享
value: 指定信号量的初始值
返回0: 成功 || 返回-1并设置errno: 失败
*/
int sem_init(sem_t * sem, int pshared, unsigned int value);

sem_init函数用于初始化一个未命名的信号量。初始化一个已经被初始化的信号量将导致不可预期的结果。

1
2
3
4
5
6
/*
引用方式: #include <semaphore.h>
sem: 指定操作的信号量
返回0: 成功 || 返回-1并设置errno: 失败
*/
int sem_destroy(sem_t * sem);

sem_destroy销毁信号量以释放其占用的资源,销毁一个正被其他线程等待的信号量将导致不可预期的结果。

1
2
3
4
5
6
/*
引用方式: #include <semaphore.h>
sem: 指定操作的信号量
返回0: 成功 || 返回-1并设置errno: 失败
*/
int sem_wait(sem_t * sem);

sem_wait以原子操作的方式将信号量的值减1。若信号量的值为0,则sem_wait将被阻塞直到信号量的值大于0。

1
2
3
4
5
6
/*
引用方式: #include <semaphore.h>
sem: 指定操作的信号量
返回0: 成功 || 返回-1并设置errno: 失败
*/
int sem_trywait(sem_t * sem);

sem_trywait与sem_wait函数的功能类似,不过它总是立即返回,不论被操作的信号量是否具有非0值,即sem_wait的非阻塞版本。若信号量的值非0,sem_trywait以原子操作的方式将信号量的值减1,否则它将返回-1并设置errno为EAGAIN。

1
2
3
4
5
6
/*
引用方式: #include <semaphore.h>
sem: 指定操作的信号量
返回0: 成功 || 返回-1并设置errno: 失败
*/
int sem_post(sem_t * sem);

sem_post以原子操作的方式将信号量的值加1,当信号量的值大于0时其他正在调用sem_wait等待信号量的线程将被唤醒。