信号量(semaphore)

进程间通信-信号量



1、为什么要使用信号量

为了防止多个程序同时访问一个共享资源而引发的一系列问题,故有这样一种方法,在任何一个时刻只有一个执行线程访问代码的临界区(临界区是指访问临界资源的代码),而信号量就可以提供这样的访问机制,同一时刻只允许一个线程访问临界区,也就是说信号量是用来协调进程共享资源访问的,也就是说信号量用来协调进程对共享资源访问的,其中共享内存就是用信号量实现的。

2、信号量的工作原理

由于信号量只能进行两种操作等待和发送信号,他们是p(sv)操作,v(sv)操作。

p(sv)操作:如果sv的值大于0.他就减1,如果sv的值等于0,它就挂起进程的执行。

v(sv)操作:如果有其他进程因等待sv而挂起,则就让他恢复运行,如果没有进程因等待它而挂起,就让他加1.

举个例子,就是
两个进程共享信号量sv,一旦其中一个进程执行了P(sv)操作,它将得到信号量,并可以进入临界区,使sv减1。而第二个进程将被阻止进入临界区,因为
当它试图执行P(sv)时,sv为0,它会被挂起以等待第一个进程离开临界区域并执行V(sv)释放信号量,这时第二个进程就可以恢复执行。

3、Linux信号量机制

Linux提供了一组精心设置的信号量接口来对信号量进行操作。这些函数都是用来对组的信号量进行操作,他们被声明在sys/sem.h中。

4、信号量的使用

(1)创建信号量

semget函数创建一个信号量集或者访问一个已存在的信号量集

int semget (key_t key, int nsem, int oflag)

返回值是一个称为信号量标识符的整数,semop和semctl函数将使用它。成功返回信号量的标示符,失败返回-1

key:由ftok()函数得到,

nsem:创建信号量中的个数

oflag:

IPC_CREAT:若内核中不存在键值与key相等的信号量集,则创建,否则,返回此信号量集的标识符

IPC_EXCL:单独使用无意义

IPC_CREAT | IPC_EXCL :创建一个新的信号量集并返回信号量集的标识符,否则,返回-1.

(2)打开信号量(完成对信号量的PV操作)

用semget打开一个信号量后,对其中一个或多个信号量操作就是用semop来执行。

int semop (int semid, struct sembuf * opsptr, size_t nops)

semid:信号量集标识符

nsops:进行操作信号量的个数,即sops结构变量的个数,需大于或等于1.

opspt:是一个指针,它指向一个信号量操作数组,信号量操作由sembuf结构表示

struct sembuf{
 short sem_num; // 除非使用一组信号量,否则它为0 
 short sem_op; // 信号量在一次操作中需要改变的数据,通常是两个数,
 // 一个是-1,即P(等待)操作,一个是+1,即V(发送信号)操作 
 short sem_flg; // 通常为SEM_UNDO,使操作系统跟踪信号,并在进程没有释放该信号量而终止时,
 // 操作系统释放信号量 
};

当操作信号量(semop)时,flg可以设置SEM_UNDO标识;SEM_UNDO用于将修改的信号量值在进程正常退出(调用exit退出或main执行完)或异常退出(如段异常、除0异常、收到KILL信号等)时归还给信号量。进程以SEM_UNDO方式操作后;在进程未退出时,可以改变信号量的值,在进程退出时,将修改的值归还给信号量,信号量变成原来的值。

(3)在指定信号集或者信号集上的某个信号进行操作

int semctl(int semid,int semnum,int cmd,union semun arg)

semid: 信号量集标识符

semnum:信号量集数组上的下标,表示某一个信号量

第四个参数是可选的,取决于第个信号(操作对象)

参数cmd指定以下10种命令中的一种,在semid指定的信号量集合上执行此命令。

IPC_STAT   读取一个信号量集的数据结构semid_ds,并将其存储在semun中的buf参数中。

IPC_SET     设置信号量集的数据结构semid_ds中的元素ipc_perm,其值取自semun中的buf参数。

IPC_RMID  将信号量集从内存中删除。

GETALL      用于读取信号量集中的所有信号量的值。

GETNCNT  返回正在等待资源的进程数目。

GETPID      返回最后一个执行semop操作的进程的PID。

GETVAL      返回信号量集中的一个单个的信号量的值。

GETZCNT   返回这在等待完全空闲的资源的进程数目。

SETALL       设置信号量集中的所有的信号量的值。

SETVAL      设置信号量集中的一个单独的信号量的值。

5.例子

时间: 2024-10-01 01:28:37

信号量(semaphore)的相关文章

经典线程同步 信号量Semaphore

阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇一个经典的多线程同步问题> <秒杀多线程第五篇经典线程同步关键段CS> <秒杀多线程第六篇经典线程同步事件Event> <秒杀多线程第七篇经典线程同步互斥量Mutex> 前面介绍了关键段CS.事件Event.互斥量Mutex在经典线程同步问题中的使用.本篇介绍用信号量Semaphore来解决这个问题. 首先也来看看如何使用信号量,信号量Semaphore常用有三个函数,使用很方便.下面是这几个函数的原型和使

秒杀多线程第八篇 经典线程同步 信号量Semaphore

版权声明:本文为博主原创文章,未经博主允许不得转载. 阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇一个经典的多线程同步问题> <秒杀多线程第五篇经典线程同步关键段CS> <秒杀多线程第六篇经典线程同步事件Event> <秒杀多线程第七篇经典线程同步互斥量Mutex> 前面介绍了关键段CS.事件Event.互斥量Mutex在经典线程同步问题中的使用.本篇介绍用信号量Semaphore来解决这个问题. 首先也来看看如何使用信号量,信号量Semaphore

java 信号量Semaphore

在很多情况下,可能有多个线程需要访问数目很少的资源.假想在服务器上运行着若干个回答客户端请求的线程.这些线程需要连接到同一数据库,但任一时刻 只能获得一定数目的数据库连接.你要怎样才能够有效地将这些固定数目的数据库连接分配给大量的线程? 答:1.给方法加同步锁,保证同一时刻只能有一个人去调用此方法,其他所有线程排队等待,但是此种情况下即使你的数据库链接有10个,也始终只有一个处于使 用状态.这样将会大大的浪费系统资源,而且系统的运行效率非常的低下. 2.另外一种方法当然是使用信号量,通过信号量许

JAVA多线程--信号量(Semaphore)

简介 信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确.合理的使用公共资源. 一个计数信号量.从概念上讲,信号量维护了一个许可集.如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可.每个 release() 添加一个许可,从而可能释放一个正在阻塞的获取者.但是,不使用实际的许可对象,Semaphore 只对可用许可的号码进行计数,并采取相应的行动.拿到信号量的线程可以进入代码,否则就等待.通过acqu

C# 多线程之一:信号量Semaphore

通过使用一个计数器对共享资源进行访问控制,Semaphore构造器需要提供初始化的计数器(信号量)大小以及最大的计数器大小 访问共享资源时,程序首先申请一个向Semaphore申请一个许可证,Semaphore的许可证计数器相应的减一,当计数器为0时,其他申请该信号量许可证的线程将被堵赛,直到先前已经申请到许可证的线程释放他占用的许可证让计数器加一,这样最近去申请许可证的线程将会得到竞争得到被释放的许可证. 常见的操作方法 WaitOne():申请一个许可证  Release():释放占用的许可

Java多线程与并发库高级应用之信号量Semaphore

JDK1.5提供了一个计数信号量Semaphore类.Semaphore 通常用于限制可以访问某些资源(物理或逻辑的)的线程数目,并提供了同步机制. Semaphore提供了两个构造器来创建对象: 1)Semaphore(int permits):创建具有给定的许可数和非公平的公平设置的Semaphore. 2)Semaphore(int permits, boolean fair):创建具有给定的许可数和给定的公平设置的Semaphore.如果此信号量保证在争用时按先进先出的顺序授予许可,则为

Java多线程-新特征-信号量Semaphore

简介信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确.合理的使用公共资源. 概念Semaphore分为单值和多值两种,前者只能被一个线程获得,后者可以被若干个线程获得. 以一个停车场运作为例.为了简单起见,假设停车场只有三个车位,一开始三个车位都是空的.这时如果同时来了五辆车,看门人允许其中三辆不受阻碍的进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待.这时,有一辆车离开停车场,看门人得知后,

信号量(Semaphore)

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Threading; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class For

linux系统编程:线程同步-信号量(semaphore)

线程同步-信号量(semaphore) 生产者与消费者问题再思考 在实际生活中,只要有商品,消费者就可以消费,这没问题.但生产者的生产并不是无限的,例如,仓库是有限的,原材料是有限的,生产指标受消费指标限制等等.为了进一步,解决好生产者与消费者问题,引入信号量进机制. 信号量 信号量(semaphore)是互斥量的升级版:互斥量的状态为0或1,而信号量可以为n.也就是说,使用互斥量时,最多允许一个线程进入关键区,而信号量允许多个,具体值是信号量当前的内部值. 相关函数 sem_t //信号量类型

java笔记--对信号量Semaphore的理解与运用

java Semaphore 信号量的使用: 在java中,提供了信号量Semaphore的支持. Semaphore类是一个计数信号量,必须由获取它的线程释放, 通常用于限制可以访问某些资源(物理或逻辑的)线程数目. 一个信号量有且仅有3种操作,且它们全部是原子的:初始化.增加和减少 增加可以为一个进程解除阻塞: 减少可以让一个进程进入阻塞. --如果朋友您想转载本文章请注明转载地址"http://www.cnblogs.com/XHJT/p/3910406.html "谢谢-- 信