码迷,mamicode.com
首页 > 其他好文 > 详细

信号量互斥编程

时间:2016-06-04 16:29:03      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:

在程序中利用信号量互斥来解决公示板问题

背景知识

1、信号灯的概念

信号灯,又被称为信号量(semaphore),是IPC(进程间通信)的方式之一。它可以用来保证两个或多个关键代码段不被多个进程并发调用。每个信号灯都有个semval,用于记录信号灯的值。在进入一个关键代码段之前,进程必须获取一个信号量,使semval减1;一旦该关键代码段完成了,那么该进程必须释放信号量,使semval加1.其它想进入该关键代码段的进程,如果semval是0,就必须等待直到第一个进程释放信号量。

2、信号灯的用法

使用共享内存进行进程间通讯一般会经历下面几步:

1)建立信号灯集:进程通过调用函数semget来创建或者获得一个信号灯集;

2)初始化semval:通过semctl使用SETVAL命令来初始化信号灯的值(semval);

3)获取与释放semval:通过函数semop来获取或者释放信号灯,其中获取对应于semval值减1,释放对应于semval值加1.

4)删除信号灯集:当进程结束使用信号灯时,使用semctl通过IPC_RMID命令来删除它。

3、函数参考表

semget:

函数功能:创建与打开信号灯集

头文件:#include<sys/types.h>

#include<sys/ipc.h>

#include<sys/sem.h>

函数原型:int semget(key_t key,int nsems,int semflg);

参数说明:key:表示信号灯集的键值。当key的取值为IPC_PRIVATE,则函数semget()将创建一个新的信号灯集。

nsems:表示创建的信号灯集中的信号灯个数。

semflg:表示的操作类型,也可用于设置信号灯的访问权限,两者通过‘|‘连接表示。

返回值:成功,则返回信号灯的IPC标识符。失败,则返回-1,errno存储错误原因。

EACCESS:没有权限

EEXIST:信号灯集已经存在,无法创建。

EIDRM:信号灯集已经删除。

ENOENT:信号灯集不存在,同时没有使用IPC_CREAT.

ENOMEM:没有足够的内存创建新的信号灯集。

ENOSPC:超出限制。

 

ftok:

函数功能:通过将文件路径名和子序号,获得System V IPC 键值(即创建消息队列、共享内存所用的键值)

#include<sys/types.h>

#include<sys/ipc.h>

函数原型:key_t ftok(const char *pathname,int proj_id);

参数说明:pathname:指定的带路径的文件名。

proj_id:子序号id,或称工程id。

如指定文件的索引节点号为65538,,换算成16进制为0x010002,而指定的ID值为38,换算成16进制为0x26,则最后的key_t返回值为0x26010002。

返回值:成功,则返回System V IPC键值。失败,则返回-1,errno储存错误原因。

 

semop

函数功能:信号灯的操作函数

头文件:#include<sys/types.h>

#include<sys/ipc.h>

#include<sys/sem.h>

函数原型:int semop(int semid,struct sembuf *sops,unsigned nsops);

参数说明:semid:待操作的信号灯集ID。

sops:指向待操作的信号灯结构体(数组)。sembuf结构体包含了对于某个信号灯操作方法的信息,其成员如下:

unsigned short sem_num;//信号灯编号,从0开始

short sem_op;//为正时,代表释放的信号灯值,为负时代表获取是信号灯值

short sem_flg;//操作的标识

nsops:表示要操作的信号灯数。

返回值:成功时,这个函数返回共享内存的起始地址,失败时返回-1.

semctl

函数功能:信号灯的控制

头文件:#include<sys/types.h>

#include<sys/ipc.h>

#include<sys/sem.h>

函数原型:int semctl(int semid,int semnum,int cmd,union semun arg);

参数说明:

semid:信号灯集的ID.

semnum:操作的信号灯编号。

cmd:是控制命令,常用的命令有

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

GETPID:获得sempid

GETVAL:获得semval

SETVAL:设置semval

arg:是一个共同体类型的副本。其中各个量的使用情况和参数cmd的设置有关。

返回值:失败时返回-1,成功返回与cmd相关的正数,例如:

GETPID:返回sempid

SETVAL:返回semval

st1.c

技术分享

技术分享

st2.c

技术分享

技术分享

执行st1,进入睡眠

技术分享

st2去获取信号量失败,则进行阻塞

技术分享

当st1程序操作完成并释放了信号量之后,则st2重新获取信号量成功后,才得到运行。

技术分享

查看board.txt文件

技术分享

 

技术分享

信号量互斥编程

标签:

原文地址:http://www.cnblogs.com/gary-guo/p/5558861.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!