Linux 多线程 信号量 屏障

本文介绍了Linux系统中多线程同步的两种机制:信号量和屏障。详细阐述了信号量的初始化、P/V操作及其在解决生产者消费者问题中的应用,并解释了信号量配合互斥量的重要性。同时,对屏障的概念、初始化、等待函数及多线程屏障示例进行了讲解,展示了如何通过屏障实现线程间的同步集合。
摘要由CSDN通过智能技术生成

阅读了《Unix/Linux系统编程》中关于Pthread信号量和屏障的内容,结合网上资料进行了整理
参考资料

6. 信号量

信号量是进程/线程同步的一种机制。它是一种特殊的变量,它可以被增加或减少,但对信号量的访问被保证是原子操作。

POSIX中,信号量是sem_t类型。可以对信号量进行P/V操作,POSIX中的信号量中有一个计数值,P操作对信号量-1,V操作对信号量+1。

需要inculude<semaphore.h>

6.1 信号量初始化

int sem_init(sem_t * sem, int pshared, unsigned int value)
  • 参数sem:指向信号量变量的指针
  • pshared:是否在多个进程中使用信号量(0线程同步;1进程同步)
  • value:初始计数值

6.2 信号量P/V操作

P操作:

对信号量进行P操作。当信号量值为0,线程阻塞等待V操作唤醒(线程被投入睡眠,等待该信号量值变为大于0,再将其减1并返回 );否则信号量值-1并返回。这里对信号量的-1是原子性的。

int sem_wait(sem_t * sem)

V操作:

对信号量进行V操作。信号量值+1,然后唤醒等待该信号量值变为正数的任意一个线程(注意如果有两个阻塞在该信号量P处的线程,那么该信号量的V操作只能唤醒其中一个阻塞的线程)。这里对信号量的+1是原子性的。

int sem_post(sem_t *__sem)

6.3 信号量解决生产者消费者问题:

定义一个int类型全局变量num,并指定其上限。创建10个生产者线程不停往里面+1直到加到上限,然后就不能加了,要等消费者减后才能继续加;创建10个消费者线程不停往里面-1直到减到0,然后就不能减了,要等生产者加后才能继续减。

注意在多线程问题中信号量往往要配合互斥量一起使用。因为如果多个线程P(sem)后同时操作全局共享变量,会由于同时访问导致出错(因为该访问全局共享资源的操作可能不是原子性的)。如下面的代码如果把互斥锁的上锁解锁语句注释掉,那么结果会出错(num的值会小于0或大于上限)

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdlib.h>
#define MAX 5//num范围为0-5
int num;//全局共享变量
sem_t* full;//信号量full,有多少个产品
sem_t* empty;//信号量empty,表示还能生产多少个产品就满了
pthread_mutex_t * m;
//消费者线程入口函数
void* consumer(void*arg){
   
    for(int i = 0 ; i < 30 ;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值