目录
一 介绍
由于线程和进程一样,也需要考虑同步操作,线程的同步操作主要有POSIX信号量,互斥锁以及条件变量。其中,POSIX信号量和之前介绍的IPC信号量一样,具有相同的功能。接下来,我们直入主题,具体来看看POSIX信号量如何使用吧!
二 POSIX信号量的相关函数
POSIX信号量相关函数在semaphore.h头文件当中。
2.1 信号量的初始化
int sem_init(sem_t*sem,int pshared,unsigned int value);
函数功能:初始化一个信号量,并且其初值为value。
函数参数:
1.pshared:取0时信号量只属于当前进程的局部信号量,取1时信号量可以被多个进程共享。
2.value:信号量sem的初值。
2.2 信号量的销毁
int sem_destroy(sem_t*sem);
函数功能:用于销毁信号量sem,并且释放内核中资源。如果释放正在被其他线程等待的信号量将导致不可预估的后果。
2.3 信号量减一操作(阻塞)
int sem_wait(sem_t*sem);
函数功能:用于将信号量的值减一。如果信号量当前值为0,则会阻塞直到该信号量的值非零。
2.4 信号量减一操作(非阻塞)
int sem_trywait(sem_t*sem);
函数功能:用于将信号量的值减一。如果信号量的当前值为0,则不阻塞之间返回-1,设置错误码EAGAIN。
2.5 信号量加一操作
int sem_post(sem_t*sem);
函数功能:用于将信号量的值加一,如果有其他线程阻塞在sem_wait()函数中,则会唤醒该线程。
三 POSIX信号量的使用
测试代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<semaphore.h>
sem_t sem;
int data = 0;
void* thread()
{
sem_wait(&sem);
data++;
printf("数据大小:%d\n", data);
sleep(2);
data--;
sem_post(&sem);
}
int main()
{
int ret = sem_init(&sem, 0, 2);
if(ret != 0)
{
printf("创建信号量失败");
return -1;
}
pthread_t tid1, tid2, tid3;
ret = pthread_create(&tid1, NULL, thread, NULL);
if(ret != 0)
{
printf("创建线程1失败");
return -1;
}
ret = pthread_create(&tid2, NULL, thread, NULL);
if(ret != 0)
{
printf("创建线程2失败");
return -1;
}
ret = pthread_create(&tid3, NULL, thread, NULL);
if(ret != 0)
{
printf("创建线程3失败");
return -1;
}
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
pthread_join(tid3, NULL);
sem_destroy(&sem);
return 0;
}
加信号量:
不加信号量: