Linux信号量
创始人
2025-05-30 21:37:33
0次

        信号量是一个特殊的变量,一般取正数值。它的值代表允许访问的资源数目, 获取资源
时,需要对信号量的值进行原子减一,该操作被称为 P 操作。当信号量值为 0 时,代表没有
资源可用, P 操作会阻塞。释放资源时,需要对信号量的值进行原子加一,该操作被称为 V
操作。信号量主要用来同步进程。 信号量的值如果只取 0,1,将其称为二值信号量。如果信
号量的值大于 1,则称之为计数信号量。

        临界资源:同一时刻,只允许被一个进程或线程访问的资源
        临界区:访问临界资源的代码段

2.2信号量的使用

操作信号量接口介绍:

# include 
# include 
# include 
int semget(key_t key,int nsems,int semflg);
/*semget()创建或者获取已存在的信号量
*semget()成功返回信号量的ID,失败返回-1
*key :两个进程使用相同的key值,就可以使用同一个信号量
*nsems:内核维护的是一个信号量集,在新建信号量时,其指定信号量集中信号量的个数
semflg可选:IPC_CREAT IPC_EXCT
*/
int semop(int semid,struct sembuf*sops,unisgned nsops);
//semop()对信号量进行改变,做p操作或这v操作
//semop()成功返回0,失败返回-1
//struct sembuf
{unisgned short sem_num;//指定信号量集中的信号量下标short   sem_op;//其值为-1,代表p操作,其值为1,代表v操作short   sem_flg;//SEM_UNDO
}
int semctl (int semid,int semnum,int cmd,...);
/*
semctl() 控制信号量
semctl()成功返回0,失败返回-1
cmd选项:SETVAL IPC_RMID
SETVAL:用来把信号量初始化为一个已知的值。这个值通过union semun中的val成员设置。
其作用是在信号量第一次使用之前对它进行设置
IPC_RMID:用于删除一个已经无需继续使用的信号量标识符。
semtcl函数会根据command参数的不同而返回不同的值。对于SETVAL和IPC_RMID,成功是返回0,失败时返回-1.
*/

头文件sys/sem.h通常会依赖于另两个头文件sys/types.h和sys/ipc.h。一般情况下,它们都会呗sys/sem.h自动包含,因此不需要为它们明确添加相应的# include语句。

        例题:进程 a 和进程 b 模拟访问打印机,进程 a 输出第一个字符‘ a’表示开始使用打印
机,输出第二个字符‘ a’表示结束使用, b 进程操作与 a 进程相同。(由于打印机同一时刻
只能被一个进程使用,所以输出结果不应该出现 abab) ,如图所示:


 

 代码如下:

sem.h

#include 
union semun{int val;
};
void sem_init();//创建/或者已存在的信号量
void sem_p();//p 减一
void sem_v();//v 加一
void sem_destroy();//销毁

sem.c

#include 
#include 
#include 
#include 
#include "sem.h"
static int semid = -1;
void sem_init()//创建/或者已存在的信号量{semid = semget((key_t)1234,1,IPC_CREAT|IPC_EXCL|0600);if ( semid == -1 )//已存在{semid = semget((key_t)1234,1,0600);}else{union semun a;a.val = 1;//信号量的初始值if ( semctl(semid,0,SETVAL,a) == -1 ){perror("semctl error");}}}void sem_p()//p 减一{struct sembuf buf;buf.sem_num = 0;buf.sem_op = -1;//pbuf.sem_flg = SEM_UNDO;if ( semop(semid,&buf,1) == -1 ){perror("semop p error");}}void sem_v()//v 加一{struct sembuf buf;buf.sem_num = 0;buf.sem_op = 1;//vbuf.sem_flg = SEM_UNDO;
if ( semop(semid,&buf,1) == -1 ){perror("semop v error");}}void sem_destroy()//销毁{if ( semctl(semid,0,IPC_RMID) == -1 ){perror("semctl del error");}}

a.c

#include 
#include 
#include 
#include 
#include 
int main()
{sem_init();int i = 0;for( ;i < 10; i++ ){sem_p();printf("a");fflush(stdout);int n = rand() % 3;sleep(n);printf("a");fflush(stdout);sem_v();n = rand() % 3;sleep(n);}}

b.c

#include 
#include 
#include 
#include 
#include 
int main()
{sem_init();int i = 0;for( ;i < 10; i++ ){sem_p();printf("b");fflush(stdout);int n = rand() % 3;sleep(n);printf("b");fflush(stdout);sem_v();n = rand() % 3;sleep(n);}}

执行结果:

 

相关内容

热门资讯

在大吉订购APP订购交易亏损被...   近期,不少投资者反映在“大吉订购App”上投资白银、铂金等商品遭遇严重亏损。该平台宣称提供现货订...
铂银壹号APP商品订购交易亏损...   许多中小投资者误以为网上的“商品现货订购”是合规合法的理财渠道,殊不知这背后隐藏着巨大的合规风险...
兴鑫淘金APP贵金属订购交易亏...   白银、贵金属或其他商品类投资,除国家批准的正规期货交易场所及持牌期货公司外,市面上大量第三方交易...
铂银掘金APP无资质的违规平台...   铂银掘金等平台的投资者,往往是被“注册送现金”“充值返现券”“首单免亏”等广告话术吸引,进而下载...
八方淘金APP订购交易不合规,...   “八方淘金APP”“铂银掘金APP”“铂银壹号APP”等软件被指以“现货订购”为名,实际采用高杠...
在指尖订购APP订购商品亏损被...   指尖订购APP这类平台,表面是“订购交易”,实则是披着电商外衣的非法期货陷阱。绝大多数投资者被蒙...
在犀贝易购APP做商品订购交易...   市面上打着“现货投资”“贵金属交易”旗号的APP并不少,但真正合规、受监管的平台并不多。犀贝易购...
易达淘金APP虚假商品订购交易...   易达淘金APP存在严重的虚假宣传与违规交易行为。该平台打着“商品订购”的旗号,实则通过不合规的交...
大浪淘金APP白银订购亏损被骗...   大浪淘金APP最隐蔽的套路,在于其完全封闭的内盘交易系统。表面上,它宣称与国际贵金属市场接轨;实...
一品好购APP上订购白银出现亏...   一品好购APP原名“一品订购”,运营方为上海宝智未来信息技术有限公司。近期不少投资者反映在该平台...
九州订购APP贵金属订购投资骗...   九州订购APP正通过抖.音、快手、今日头条等平台大量投放投资广告,用“5元起投”“充值返现”“0...
坚锅淘金APP交易软件并不正规...   当前,市面上大量所谓的“现货商城订购”交易软件,早已偏离了正常的实物商品买卖,演变为高杠杆、高手...
斗金订购APP贵金属期货交易骗...   斗金订购APP的投资者往往被铺天盖地的广告宣传所诱导——注册即送现金、充值返现券等看似诱人的福利...
警惕!云启购APP违规经营,披...   "5元起投、充值返现、稳赚不赔"——这些诱人的广告语背后,可能是一个精心设计的金融陷阱。  近期...
量子淘金APP贵金属投资不合规...   "4元起投""充值返券""月入过万"——这些极具诱惑力的广告语在短视频平台、社交软件上铺天盖地。...
鑫汇智投APP贵金属商品订购骗...   鑫汇智投APP非法期货投资骗局,受害者在投资过程中根本不懂交易,也不去研究和验证这个平台是否正规...
矅光智策APP平台违规经营非法...   矅光智策APP对外宣称是“商城订购”“现货交易”,但查询其经营范围,并未显示具备开展现货期货交易...
黄金珠宝怎么选?内侧刻字都代表... 潮新闻客户端 记者 马焱 通讯员 任倩影 9月8日下午,“云游杭州 乐购金秋”——“浙城·浙放心”活...
原创 冰... 最近全球国债市场正在上演魔幻一幕: 美债、日债、欧债遭遇猛烈抛售,收益率冲到几十年新高,美国财政部都...
日韩股市开盘表现分化 上证报中国证券网讯 9月9日,日韩股市开盘表现分化,韩国综合指数开盘上涨0.26%,报6972.87...