POSIX多线程笔记(7):信号量(Semaphore)

本文介绍了信号量的概念,作为操作系统中的互斥和同步机制。详细阐述了POSIX无名信号量的使用,包括初始化、销毁、signal和wait操作。同时提供了一个实例,展示如何利用信号量确保两个线程在递增变量时保持差值不超过5。
摘要由CSDN通过智能技术生成

信号量的概念

1965年,E.W.Dijkstra提出了信号量的概念,之后信号量即成为操作系统实现互斥和同步的一种普遍机制。信号量是包含一个非负整型变量,并且带有两个原子操作wait和signal。wait还可以被称为down、P或lock,signal还可以被称为up、V、unlock或post。

如果信号量的非负整形变量S大于零,wait就将其减1,如果S等于0,wait就将调用线程挂起。对于signal操作,如果有线程在信号量上阻塞(此时S等于0),signal就会解除对某个等待线程的阻塞,使其从wait中返回,如果没有线程阻塞在信号量上,signal就将S加1。

由此可见,S可以被理解为一种资源的数量,信号量即是通过控制这种资源的分配来实现互斥和同步的。如果把S设为1,信号量即可实现互斥量的功能。如果S的值大于1,那么信号量即可使多个线程并发运行

POSIX信号量是一个sem_t类型的变量,但POSIX有两种信号量的实现机制:无名信号量命名信号量。无名信号量可以用在共享内存的情况下,比如实现进程中各个线程之间的互斥和同步。命名信号量通常用于不共享内存的情况下,比如不共享内存的进程之间。

信号量相关的函数和数据结构需要引用头文件semaphore.h

POSIX无名信号量

在使用信号量之前,必须对其进行初始化。sem_init函数初始化指定的信号量,它的形式为:

int sem_init(sem_t *sem, int pshared, unsigned value); 

参数sem指向要初始化的信号量,参数value为信号量的初始值。参数pshared用于说明信号量的共享范围,如果pshared为0,那么该信号量只能由初始化这个信号量的进程中的线程使用,如果pshared非零,任何可以访问到这个信号量的进程都可以使用这个信号量。如果成功,sem_init返回0,如果不成功,sem_init返回-1并设置errno。

函数sem_destroy销毁一个指定的信号量,它的形式为:

int sem_destroy(sem_t *sem); 

参数sem为指向要销毁的信号量的指针。如果成功,sem_destroy返回0,如果不成功,sem_destroy返回-1并设置errno。如果*sem不是有效的信号量,sem_destroy就将errno置为EINVAL。

sem_post函数实现对指定信号量的signal操作,它的形式为:

int sem_post(sem_t *sem); 

如果成功,sem_post返回0。如果不成功,sem_post返回-1并设置errno。如果*sem不是有效的信号量,sem_post就将errno置为EINVAL。

sem_wait函数实现对指定信号量的wait操作。sem_trywait函数与sem_wait类似,只是在试图对一个为零的信号量进行操作时,它不会阻塞调用线程,而是立即返回,类似于互斥量操作中的pthread_mutex_trylock()。这两个函数的形式为:

int sem_wait(sem_t *sem); 
int sem_trywait(sem_t *sem);

如果成功,这两个函数返回0,如果不成功,这些函数返回-1并设置errno。如果*sem不是有效的信号量,sem_ wait就将errno置为EINVAL

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值