进程同步与互斥.ppt
《进程同步与互斥.ppt》由会员分享,可在线阅读,更多相关《进程同步与互斥.ppt(31页珍藏版)》请在三一文库上搜索。
1、进程同步与互斥,2019/7/20,2,Linux提供下列3个有关信号量的系统调用函数: semget() semop() semctl() 下面分别予以介绍。,2019/7/20,3,1.创建一个新的信号量集或获取一个已经存在的信号量集 命令格式: int semget(key_t key, int nsems, int semflg); 返回值: 正确返回:信号量集的标识符 错误返回:-1,2019/7/20,4,1.创建一个新的信号量集或获取一个已经存在的信号量集,参数说明: key信号量集的key值: 使用IPC_PRIVATE,由系统产生key值并返回标识符,或者返回key值已存在的
2、信号量集的标识符。 key值不为IPC_PRIVATE而是由用户指定一个非0整型数值,则对信号量集的打开或存取操作依赖于semflag参数的取值。 nsems指定打开或者新创建的信号量集将包含的信号量的数目;如果该key值的信号量集已存在,而semflg只指定了IPC_CREAT标志,那么参数nsems必须与原来的值一致,否则也会返回错误信息。该参数最大值在linux/sem.h中被定义: #define SEMMSL 250 /* = 8 000 */ semflg当key值不为IPC_PRIVATE: 若只设置semflag的IPC_CREAT位,则创建一个信号量集,如果该信号量集已经存在
3、,则返回其标识符 若设置semflag的IPC_CREAT|IPC_EXCL位,则创建一个新的信号量集,如果该key值的信号量集已经存在则返回错误信息 只设置IPC_EXCL位而不设置IPC_CREAT位没有任何意义。,2019/7/20,5,1.创建一个新的信号量集或获取一个已经存在的信号量集,实验中,使用该调用创建一个只含一个信号量的信号量集,格式为: semid=semget(IPC_PRIVATE,1, IPC_CREAT|0666); 其中的IPC_PRIVATE可以使用具体的整型数值取代。,2019/7/20,6,2.对信号量的P、V操作,命令格式: int semop(int s
4、emid, struct sembuf * sops, unsigned nsops); 返回值: 正确返回:0 错误返回:-1 参数说明: semid信号量集的标识符,由semget()得到。 sops指向一个sembuf结构数组,该数组的每个元素对应一次信号量操作。,2019/7/20,7,2.对信号量的P、V操作,其sembuf数据结构如下: struct sembuf unsigned short sem_num; /* semaphore index in array */ short sem_op; /* semaphore operation */ short sem_flg;
5、/* operation flags */ ; 其中的参数含义如下所示:,2019/7/20,8,2.对信号量的P、V操作,信号量的sem_num值标明它是信号量集的第几个元素,第一个信号量为0,第二个为1,依次类推。 semop确定对sem_num指定的信号量采取何种操作,它可以为负数、正数和零。 如果sem_op为负数:则相当于P操作,从信号量的值中减去sem_op的绝对值: 其差如果大于0,则表示该进程可以使用临界资源进入临界区; 其差如果小于0,在没有指定IPC_NOWAIT的情况下,该进程睡眠,并插入sem_queues等待队列尾部,直到请求的条件得到满足;如果指定了IPC_NOWA
6、IT,则出错返回。 如果sem_op为正数:此时相当于V操作,把它的值加到信号量中,这也意味着该进程释放资源。如果是互斥则出临界区,释放临界资源。 如果sem_op为0:则该进程将睡眠直到信号量的值也为0。 系统会按顺序检查信号量等待队列(sem_pending)中的每一个成员,查看在当前信号量的状态下,其请求的操作是否可以成功,如果可以,则将它从等待队列中唤醒,并插入到就绪队列中等待调度运行。 sem_flg指明操作的执行模式,它有两个标志位: IPC_NOWAIT:指明以非阻塞方式操作信号量。 SEM_UNDO: 指明内核为信号量操作保留恢复值 nsops是第二个参数所指向的sembuf结
7、构数组中元素的个数,如果只有一个信号量nsops值为1。,2019/7/20,9,2.对信号量的P、V操作,在实验中,使用该系统调用实现P、V操作,使用格式为: struct sembuf P,V; semop(semid, /对信号量semid执行V操作,2019/7/20,10,3信号量集的控制函数,命令格式: int semctl(int semid, int semnum, int cmd, union semun arg); 返回值: 操作成功返回:根据cmd的不同返回需要的值或0 错误返回:-1,2019/7/20,11,3信号量集的控制函数,参数说明: semid信号量集的标识符
8、,由semget()得到; semnum指定semid信号量集的第几个信号量,在撤消信号量集时,此参数可以缺省; cmd用于指定操作类别: SETVAL:置信号量semval域值为arg.val。 IPC_RMID:删除指定信号量集。能够进行此项操作的进程限于超级用户、 sem_perm.cuid或sem_perm.uid。,2019/7/20,12,3信号量集的控制函数,实验中使用该系统调用实现以下功能: 为信号量赋初值,格式为: union semun arg; arg.val=初值; semctl(semid,0,SETVAL,arg); 其中0表示第0个信号量,arg的值由arg.va
9、l决定,所以必须事先为arg.val赋值。 撤消信号量集,格式为: semctl(semid,IPC_RMID,0); 上述系统调用使用下列头函数: #include #include,2019/7/20,13,信号量及其P、V操作的实现,信号量及其P、V操作的实现方式归纳如下: 1 定义信号量标识符:int semid; 如果有n个信号量,则需要分别定义n个不同的信号量标识符。 2 定义信号量数据结构 定义P、V操作所用的数据结构:struct sembuf P,V; 定义给信号量赋初值的参数数据结构:union semun arg; 3 申请只有一个信号量的信号量集semid=semget
10、(IPC_PRIVITE,1,IPC_0666); 其中,第一个参数:IPC_PRIVATE由系统产生key值,也可以由用户使用具体的整型数值作为key值指定;第二个参数表示信号量集中只有一个信号量;操作权限取决于最后一个参数,0666表示任意用户可读可写,只设置semflag的IPC_CREAT位,则创建一个信号量集,如果该信号量集已经存在,则返回其标识符。 4 分别对每个信号量semid赋初值 arg.val=初值; semctl(semid,0,SETVAL,arg);,2019/7/20,14,信号量及其P、V操作的实现,5. 定义信号量的P操作(供所有信号量的P操作使用) P.sem
11、_num=0; P.sem_op=-1; /*-1表示P操作时对信号量减1*/ P.sem_flg=SEM_UNDO; 6. 定义信号量的V操作(供所有信号量的V操作使用) V.sem_num=0; V.sem_op=1; /*1表示V操作时对信号量加1*/ V.sem_flg=SEM_UNDO; 7. 对信号量semid执行P操作:semop(semid, 因为信号量不是普通变量,对它赋初值只能通过系统调用函数semctl(semid,0,SETVAL,arg)进行,其值的修改只能通过P、V操作,而不能使用普通的赋值语句。 因此其初值和信号量的P、V操作需要事先定义好以后,然后才能在进程中执
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 进程 同步
链接地址:https://www.31doc.com/p-3174696.html