线程同步和互斥---线程信号量
信号量从本质上是一个非负整数计数器,是共享资源的数目,通常被用来控制对共享资源的访问。
信号量可以实现线程的同步和互斥
通过sem_post()和wem_wait()函数对信号量进行加减操作从而解决线程的同步和互斥。
信号量数据类型
sem_t
信号量的创建和销毁
#include <semaphore.h>
int sem_init(sem_t *sem,int pshared,unsigned value);
int sem_destroy(sem_t *sem)
返回值:成功返回0,失败返回错误编号
参数:
sem:信号量指针
pshared:是否在进程间共享的标志,0为不共享,1为共享
value:信号量的初始值
信号量的加和减操作
#include <semaphore.h>
int sem_post(sem_t *sem);//增加信号量的值
int sem_wait(sem_t *sem);//减少信号量的值
int sem_trywait(sem_t *sem);//sem_wait()的非阻塞版本
返回值:成功返回0,出错返回错误编号
调用sem_post()一次信号量加1操作
调用sem_wait()一次信号量减1操作
当线程调用sem_wait()后,若信号量的值小于0则线程阻塞。只有其他线程在调用sem_post对信号量作加操作后并且其值大于或者等于0时,阻塞的线程才能继续运行
例子:
启动三个子线程,通过线程信号量控制子线程的执行顺序 c->b->a
#include <pthread.h>
#include <semaphore,h>
#include <stdio.h>
#include <stdlib.h>
//定义两个线程信号量
sem_t sem1;
sem_t sem2;
void *a_fn(void *arg)
{
sem_wait(&sem1);//减1,阻塞
printf("thread a runnin\n");
return (void *)0;
}
void *b_fn(void *arg)
{
sem_wait(&sem2);//阻塞
printf("thread b runnin\n");
sem_post(&sem1);//释放线程a(对线程信号量sem1加1操作,让阻塞的线程a继续运行)
return (void *)0;
}
void *c_fn(void *arg)
{
printf("thread c runnin\n");
sem_post(&sem2);//释放线程b(对线程信号量sem2加1操作,让阻塞的线程b继续运行)
return (void *)0;
}
int main(void)
{
pthread_t a,b,c;
//线程信号量初始化,初始值为0
sem_init(&sem1,0,0);
sem_init(&sem2,0,0);
pthread_create(&a,NULL,a_fn,(void *)0);
pthread_create(&a,NULL,b_fn,(void *)0);
pthread_create(&a,NULL,c_fn,(void *)0);
pthread_join(a,NULL);
pthread_join(b,NULL);
pthread_join(c,NULL);
return 0;
}