博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
信号量互斥编程
阅读量:4285 次
发布时间:2019-05-27

本文共 2715 字,大约阅读时间需要 9 分钟。

信号量通讯的目的有两个:①实现进程互斥②实现进程同步

两个进程对同一资源同时访问有时会造成数据混乱,如进程A,B都要往同一文件写入数据,当进程A写入一部分时,进程B开始写数据,这会导致文件里的数据混乱。使用信号量互斥通讯可以解决这种问题。信号量的实质是一个数字,它标志着进程能否访问资源。信号量的操作主要有获取信号量和释放信号量。使用资源前需要成功获取信号量,使用后需要释放信号量。
信号量(又名信号灯)与其他进程间通信方式不大相同,主要用途是保护临界资源(进程互斥)。进程可以根据它判定是否能够访问某些共享资源。除了用于访问控制外,还可用于进程同步。

信号量可分为两类:

1.二值信号灯:信号灯的值只能取0或1
2.计数信号灯:信号灯的值可以取任意非负值。
信号量的编程流程一般为:
①打开信号量,获取一个标示符
②利用标示符对信号量进行操作
对信号量进行编程涉及到键值的概念。进程要打开一个文件,需要知道该文件的文件名从而找到该文件并打开,而键值类似于文件名。系统的每个ipc对象(信号量,消息队列,共享内存等)在系统中都有一个键值与之对应。不管有没有打开ipc对象,这个键值都是存在的。若要打开一个信号量则必须知道键值。有些文件不存在键值,则可指定它的键值,指定方法有两种:
①任意指定一个数。缺点是若这个数已经被别的IPC对象所使用了,则在与新创建的信号量关联时就会失败。
②构造一个尽量不会被别的IPC对象用到的数方法:使用key_t ftok( char * fname, int id )

semget函数

原型:int semget(key_t key,int nsems,int semflg)头文件:
功能:打开/创建一个信号量集合,成功返回信号量集合标示符(不是获取信号量),失败返回-1参数:key:键值 semflg:可以取值IPC_CREAT,若与key相关联的信号量不存在时会创建一个信号量集合 nsems:创建的这个信号量集合里包含的信号量数目

semctl函数

原型:int semctl(int semid,int semnum,int cmd,.../*union semun arg*/)头文件:
功能:根据cmd的值进行相应操作参数:第四个参数是可选的。semid为要操作的信号量集合标示符,semnum为指定要操作的信号量集合里具体的一个信号量,编号从0开始,cmd的取值有10种,其中一种为SETVAL,设置成员semnum的信号量的值,此时第四个参数arg就是要设置的信号量的值。

semop

原型:int semop(int semid,struct sembuf *sops,unsigned nsops)头文件:
功能:操作信号量,成功返回0,失败返回-1参数:semid:要操作的信号量集合标示符nsops:要操作多少个信号量struct sembuf结构为:struct sembuf{ unsigned short sem_num; /*指定要操作的信号量集合里具体的一个信号量,编号从0开始*/ short sem_op; /*对信号量的操作,如为-1表示对信号量进行减1操作。只有使结果为非负的操作才能成功操作, 若操作失败则等待直至能操作成功*/ short sem_flg;};

实例

进程A往文件myfile里写数据,写入一部分后停止一段时间,然后接着写:

#include
#include
#include
#include
#include
#include
void main(){ int fd=open("/home/jx/myfile",O_RDWR|O_APPEND,0777); key_t key=ftok("/home/jx/myfile",1); /*创建键值*/ int semid=semget(key,1,IPC_CREAT); /*创建信号量集合,获取标示符*/ semctl(semid,0,SETVAL,1);/*设置信号量初始值*/ /*获取信号量*/ struct sembuf sop; struct sembuf *sops=&sop; sops->sem_num=0; sops->sem_op=-1; sops->sem_flg=SEM_UNDO; semop(semid,sops,1); write(fd,"hello ",6); sleep(10); write(fd,"world!",6); /*释放信号量*/ sops->sem_num=0; sops->sem_op=1; sops->sem_flg=SEM_UNDO; semop(semid,sops,1); close(fd);}

进程B先判断能否往文件myfile里写数据,若不能则等待

#include
#include
#include
#include
#include
#include
void main(){ int fd=open("/home/jx/myfile",O_RDWR|O_APPEND,0777); key_t key=ftok("/home/jx/myfile",1); /*创建键值*/ int semid=semget(key,1,IPC_CREAT); /*创建信号量集合,获取标示符*/ /*获取信号量*/ struct sembuf sop; struct sembuf *sops=&sop; sops->sem_num=0; sops->sem_op=-1; sops->sem_flg=SEM_UNDO; semop(semid,sops,1); write(fd,"this is a program",17); /*释放信号量*/ sops->sem_num=0; sops->sem_op=1; sops->sem_flg=SEM_UNDO; semop(semid,sops,1); close(fd);}

转载地址:http://xmigi.baihongyu.com/

你可能感兴趣的文章
45个必备的JavaScript Web开发工具
查看>>
CSS3实现酷炫导航
查看>>
编写更好的CSS必备的40个工具
查看>>
设计出色响应式网站的十个技巧
查看>>
文60个有用CSS代码片段
查看>>
trick:CSS 3+checkbox实现JQuery的6个基本动画效果
查看>>
Trick:不用table,怎么等分DIV
查看>>
《机器学习实战》KNN算法实现
查看>>
《机器学习实战》ID3算法实现
查看>>
Linux终端小技巧
查看>>
《机器学习实战》朴素贝叶斯
查看>>
《机器学习实战》Logistic回归
查看>>
协方差和相关系数的概念和含义
查看>>
概率密度函数、概率分布函数、概率质量函数
查看>>
StanFord ML 笔记 第五部分
查看>>
大数定律和中心极限定律
查看>>
StanFord ML 笔记 第六部分&&第七部分
查看>>
StanFord ML 笔记 第八部分
查看>>
《图像处理实例》 之 Voronoi 图
查看>>
TessorFlow学习 之 序言
查看>>