|
3级站长
  
- 帖子
- 375
- 精华
- 0
- 积分
- 188
- 威望
- 0
- 金钱
- -2 ZZB
- 阅读权限
- 40
- 在线时间
- 13 小时
- 注册时间
- 2007-4-21
|
1#
大 中
小 发表于 2008-10-16 12:47 只看该作者
[10-16] IPC- Sem信号量编程
1.
概念
信号量:代表资源数;
>0 代表可供并发进程使用的资源实体数;
=0 代表暂时无可用资源
<0 代表等待使用资源的进程数;
初始设置资源数=1,用于互斥的信号量;
可以通过P、V语操作而改变;
2.
创建信号量
# include <sys/types.h>
# include <sys/ipc.h>
# include <sys/sem.h>
int semget ( key_t key, int nsems, int semflg )
|
成功返回信号ID标识,否则失败返回-1.
参数
| 说明
| key
| 创建/打开信号量标识key值,由ftok产生,可以直接给常量
| nsems
| 信号ID标识的一组大小。即设置几个信号量。通常为1个
| semflg
| 创建/打开方式IPC_CREAT、IPC_EXCL,
|
key_t key, //标识信号量的关键字,有三种方法:1、使用IPC——PRIVATE让系统产生, 2、挑选一个随机数,3、使用ftok从文件路径名中产生
3 信号量控制
#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 删除信号量ID信息
IPC_EXCL 只有在信号量集不存在时创建
IPC_SET 设置信号量的许可权
SETVAL 设置指定信号量的元素的值为 agc.val
GETVAL 获得一个指定信号量的值
GETPID 获得最后操纵此元素的最后进程ID
GETNCNT 获得等待元素变为1的进程数
GETZCNT 获得等待元素变为0的进程数
| arg
| 操作值的union结构
|
union semun {
int val; /* 信号量值 */
struct semid_ds *buf; /* 信号状态结构*/
unsigned short int *array; /*同组中信号量值 */
struct seminfo *__buf; /* buffer for IPC_INFO */
};
|
4.
信号量操作
# include <sys/types.h>
# include <sys/ipc.h>
# include <sys/sem.h>
int semop ( int semid, struct sembuf *sops, unsigned nsops )
|
成功返回0,否则失败返回-1.
参数
| 说明
| semid
| 已创建的信号ID
| sops
| 具体的操作结构
| nsops
| 信号组大小
|
struct sembuf
{
short sem_num; /* 针对信号ID标志组中的下标的信号操作:
=0 第一个信号量 */
short sem_op; /* 对资源的使用或释放 */
short sem_flg; /* 操作标志:
IPC_NOWAIT:无资源时不等待返回,错误码为:EAGAIN
SEM_UNDO:若进程异常退出则由内核代为处理释放*/
}
|
5 例子:
sem.c
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
union semun {
int val; /* value for SETVAL */
struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* array for GETALL, SETALL */
/* Linux specific part: */
struct seminfo *__buf; /* buffer for IPC_INFO */
};
#define key 0x11000011
int P(int semid)
{
struct sembuf sops={0,-1,SEM_UNDO};
return (semop(semid,&sops,1));
}
int V(int semid)
{
struct sembuf sops={0,+1,SEM_UNDO};
return (semop(semid,&sops,1));
}
main()
{
int semid,ret;
union semun arg;
struct sembuf semop;
semid = semget(key,1,IPC_CREAT|0666);
if (semid == -1)
{
printf("create semget err\n");
return ;
}
arg.val = 1; //创建互斥初始资源数
ret =semctl(semid,0,SETVAL,arg);
if (ret == -1)
{
printf("ctl sem err\n");
semctl(semid,0,IPC_RMID,arg);
return ;
}
ret =semctl(semid,0,GETVAL,arg);
printf("ret af semctl =[%d]\n",ret);//打印可用信号值
P(semid); //占用资源
ret =semctl(semid,0,GETVAL,arg);
printf("ret af P=[%d]\n",ret);//打印可用信号值
/*
...................
*/
V(semid);//释放资源
ret =semctl(semid,0,GETVAL,arg);
printf("ret af V =[%d]\n",ret);//打印可用信号值
semctl(semid,0,IPC_RMID,arg);
}
|
|