POSIX标准定义了信号量接口如下,常常用于线程间同步。
#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);
int sem_destroy(sem_t *sem);
int sem_post(sem_t *sem);
int sem_wait(sem_t *sem);
- sem_init()在sem指向的地址初始化未命名的信号量
参数value指定信号量的初始值;
参数pshared为0表示该信号量在线程之间共享,非零表示在进程之间(例如父进程和子进程)共享,并且位于共享内存区域;
返回0表示成功,返回-1表示出错,可以读取errno值获取错误信息;
- sem_destroy在sem所指向的地址处销毁未命名的信号量
- sem_post()增加(unlock解锁)sem所指向的信号量。
- sem_wait()减少(lock锁定)sem指向的信号量。
如果信号量的值大于零,则继续递减,函数立即返回。如果信号量当前的值为零,则调用阻塞,直到可以执行减量(即,信号量值上升到零以上),或者信号处理程序中断调用。
程序示例
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include <time.h>
static sem_t g_sem_test;
static void *listen_thread(void *data)
{
time_t time_now;
while(1)
{
sem_wait(&g_sem_test);
time(&time_now);
printf("<%s, %d> %ld\n", __func__, __LINE__, time_now);
}
}
int main(int argc, char *argv[])
{
pthread_t td;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, 256 * 1024);
pthread_create(&td, &attr, listen_thread, NULL);
pthread_attr_destroy(&attr);
sem_init(&g_sem_test, 0, 0);
while(1)
{
sem_post(&g_sem_test);
sleep(10);
}
return 0;
}
编译运行如下图,main所在线程间隔10秒调用sem_post()增加信号量值,线程listen_thread在一个while循环中调用sem_wait()阻塞等待信号量,从该线程打印的UNIX时间戳来看间隔10秒“等到”了信号量,符合程序预期。