多线程
信号量
信号量:可以实现进程/线程间同步与互斥。
信号本质就是一个计数器 + pcb等待队列
信号量同步的实现:
通过自身的计数器对资源进行计数,并且通过计数器的资源计数,判断进程/线程是否能够符合访问资源的条件,若符合就可以访问,若不符合则提供的接口使进程/线程阻塞;其他进程/线程促使条件满足之后,可以唤醒pcb等待队列上的pcb
信号量互斥的实现:
保证计数器的计数不大于1,保证了资源只有一个,同一时间只有一个进程/线程能够访问资源,实现互斥。
代码操作
1.定义信号量:```sem_t```
2.初始化信号量
int set_t init(sem_t *sem, int pshared, unsigned int value)
sem: 定义的信号量变量; pshare: 0-用于线程间/ 非0- 用于进程间 value: 初始化信号量初值---初始资源数量有多少就是多少;成功返回0,失败返回-1
3.在访问临界资源之前,先访问信号量,判断是否能够访问: 计数-1
int sem_wait(sem_t* sem);---通过自身计数,判断是否满足访问条件,不满足则一直阻塞线程/进程
int sem_trywait(sem_t* sem);--- 不满足 则立即报错返回
int sem_timewait(sem_t* sem, const struct timespec* abs_timeout)---不满足则等待指定时间,超时后报错返回
4.促使条件满足,唤醒阻塞线程/进程: 计数+1
int sem_post(sem_t* sem);---通过信号量唤醒自己阻塞队列上的pcb
5.销毁信号量
int sem_destroy(sem_t* sem);
通过信号量实现一个生产者消费者模型—线程安全的阻塞队列
#define QUEUE_MAX 5
class RingQueue{
public:
RingQueue(int maxq = QUEUE_MAX):_queue(maxq)
,_capacity(maxq)
,_step_read(0)
,_step_write(0){
sem_init(&_lock, 0, 1); // 用于实现互斥锁
sem_init(&_sem_data, 0, 0); //数据空间计数初始为0
sem_init(&_sem_idle, 0, maxq); //空闲空间计数器初始为节点个数
}
~RingQueue(){
sem_destroy(&_lock);
sem_destroy(&_sem_data);
sem_destroy(&_sem_idle);
}
bool push(int data){
//1.判断是否能够访问资源----空闲空间的判断,空闲空间计数-1
sem_wait(&sem_idle);
//2.能访问,则加锁,保护访问过程
sem_wait(&lock);//lock计数只有不大于1,当前访问则-1,别人就不能访问了
//3.资源的访问
_queue[_step_write]