信号量
- 可以说是自动进行判断的条件变量,并添加了资源计数器的功能。
- 本质:计数器+等待队列+等待和唤醒的自动判断。
- 实现原理:通过计数器对资源进行计数,在访问临界资源前先访问信号量,通过计数器来判断是否有资源能够被访问。若计数器<=0,则使线程等待,并将计数器减一;若计数器>0,则进行资源访问,并将计数器减一。若有其他线程生产了资源,若计数器>0,则计数器加一;若计数器<=0,则计数器加一,并会唤醒一个等待队列上的线程。
基本用法示例
//通过
#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
//定义信号量变量
sem_t sem;
void *thr_con(void *arg)
{
while(1)
{
//信号量等待,是阻塞的
sem_wait(&sem);
//若资源<=0,则进行等待,并将资源数-1
//若资源>0,则运行下去,并将资源数-1
printf("Consume a resource\n");
}
return NULL;
}
void *thr_pro(void *arg)
{
while(1)
{
printf("Produce a resource\n");
sleep(1);//为了让结果看起来明显一些
//信号量唤醒
sem_post(&sem);
//唤醒等待队列,资源数+1==》
//如果此时有等待线程,那么+1的意思是少了一个等待的线程
//如果没有等待线程,那么+1意思是多了一个可以使用的资源
}
return NULL;
}
int main()
{
int ret;
//信号量初始化函数参数解释
//sem变量地址,设置线程/进程使用符号0是线程/非0是进程,设置当前资源数
sem_init(&sem,0,0);
pthread_t tid1,tid2;
ret = pthread_create(&tid1,NULL,thr_con,NULL);
if(ret != 0)
{
printf("create error\n");
return -1;
}
ret = pthread_create(&tid2,NULL,thr_pro,NULL);
if(ret != 0)
{
printf("create error\n");
return -1;
}
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
//销毁信号量函数
sem_destroy(&sem);
return 0;
}
信号量可以当作互斥锁来用
在初始化信号量的时候,要设置当前资源数目,如果只让资源数变化处于0和1这两个数,那么就可以把他当作一个互斥锁来用。