信号量函数 semget() semop() semctl()
semget()
可以使用系统调用semget() 创建一个新的信号量集,或者存取一个已经存在的信号量集 :
原型:intsemget(key_t key,int nsems,int semflg);
返回值:如果成功,则返回信号量集的IPC标识符。如果失败,则返回-1:errno=EACCESS(没有权限)
EEXIST(信号量集已经存在,无法创建)
EIDRM(信号量集已经删除)
ENOENT(信号量集不存在,同时没有使用IPC_CREAT)
ENOMEM(没有足够的内存创建新的信号量集)
ENOSPC(超出限制)
下面是一个打开和创建信号量集的程序:
intopen_semaphore_set(key_t keyval,int numsems)
{
intsid;
if(!numsems)
return(-1);
if((sid=semget(mykey,numsems,IPC_CREAT|0660))==-1)
{
return(-1);
}
return(sid);
}
};
semop()
系统调用:semop();
调用原型:int semop(int semid,struct sembuf*sops,unsign ednsops);
返回值:0,如果成功。-1,如果失败:errno=E2BIG(nsops大于最大的ops数目)
EACCESS(权限不够)
EAGAIN(使用了IPC_NOWAIT,但操作不能继续进行)
EFAULT(sops指向的地址无效)
EIDRM(信号量集已经删除)
EINTR(当睡眠时接收到其他信号)
EINVAL(信号量集不存在,或者semid无效)
ENOMEM(使用了SEM_UNDO,但无足够的内存创建所需的数据结构)
ERANGE(信号量值超出范围)
structsembuf{
ushortsem_num;/*semaphore index in array*/
shortsem_op;/*semaphore operation*/
shortsem_flg;/*operation flags*/
sem_num将要处理的信号量的个数。
sem_op要执行的操作。
sem_flg操作标志。
semctl()
系统调用:semctl();
原型:int semctl(int semid,int semnum,int cmd,union semunarg);
返回值:如果成功,则为一个正数。
如果失败,则为-1:errno=EACCESS(权限不够)
EFAULT(arg指向的地址无效)
EIDRM(信号量集已经删除)
EINVAL(信号量集不存在,或者semid无效)
EPERM(EUID没有cmd的权利)
ERANGE(信号量值超出范围)
系统调用semctl()的第一个参数是关键字值。第二个参数是信号量数目。
·IPC_STAT读取一个信号量集的数据结构semid_ds,并将其存储在semun中的buf参数中。
·IPC_SET设置信号量集的数据结构semid_ds中的元素ipc_perm,其值取自semun中的buf参数。
·IPC_RMID将信号量集从内存中删除。
·GETALL用于读取信号量集中的所有信号量的值。
·GETNCNT返回正在等待资源的进程数目。
·GETPID返回最后一个执行semop操作的进程的PID。
·GETVAL返回信号量集中的一个单个的信号量的值。
·GETZCNT返回这在等待完全空闲的资源的进程数目。
·SETALL设置信号量集中的所有的信号量的值。
·SETVAL设置信号量集中的一个单独的信号量的值。
/*arg for semctl systemcalls.*/
unionsemun{
intval;/*value for SETVAL*/
structsemid_ds*buf;/*buffer for IPC_STAT&IPC_SET*/
ushort*array;/*array for GETALL&SETALL*/
structseminfo*__buf;/*buffer for IPC_INFO*/
void*__pad;
下面的程序返回信号量的值。当使用GETVAL命令时,调用中的最后一个参数被忽略:
{
return(semctl(sid,semnum,GETVAL,0));
}
printer_usage()
{
int x;
for(x=0;x<max_printers;x++)
printf("Printer%d:%d\n\r",x,get_sem_val(sid,x));
}
{
union semunsemopts;
semopts.val=initval;
semctl(sid,semnum,SETVAL,semopts);
}
#include
#include
#include
#include
#include
#include
#define KEY1 1492
#define KEY2 1493
#define KEY3 1494
#define IFLAGS (IPC_CREAT|IPC_EXCL)
#define N 1
#define SEMKEY1 (key_t)0x2000
#define SEMKEY2 (key_t)0x2001
#define SEMKEY3 (key_t)0x2002
union semun{
int val;
struct semid_ds *buf;
unsigned short * ary;
};
int ctr_sem(key_t key,int inival)
{
union semun argument;
int id;
//if ((id=semget(key,1,IPC_CREAT))<0)
if ((id=semget(key,1,IPC_CREAT))<0)
{
printf("semget error\n");
}
argument.val=inival;
if (semctl(id,0,SETVAL,argument)<0)
{
printf("semctrl error\n");
}
return id;
}
int sem_init(key_t key, int inival)
{
int semid;
union semun arg;
semid=semget(key,1,0660|IFLAGS);
arg.val=inival;
semctl(semid, 0, SETVAL, arg);
return semid;
}
void P(int semid)
{
struct sembuf sb;
sb.sem_num=0;
sb.sem_op=-1;
sb.sem_flg=0;
semop(semid,&sb,1);
}
void V(int semid)
{
struct sembuf sb;
sb.sem_num=0;
sb.sem_op=1;
sb.sem_flg=0;
semop(semid,&sb,1);
}
int productItem()
{
static int i=1;
printf("Produce a product %d\n",i);
return i++;
}
void consumeItem(int item)
{
printf("Consume a product %d\n",item);
}
int main(void)
{
int nshm=shmget(ftok("/root",'a'),1024,IPC_CREAT);
int *buffer=(int *)shmat(nshm,0,0);
// int products=ctr_sem(KEY1/*ftok("/home/jingenl",'p')*/,0);
// int space=ctr_sem(KEY2/*ftok("/home/jingenl",'s')*/,N);
// int mutex=ctr_sem(KEY3/*ftok("/home/jingenl",'m')*/,1);
int products=sem_init(SEMKEY1,0);
int space=sem_init(SEMKEY2,N);
int mutex=sem_init(SEMKEY3,1);
int i=0,j=0;
if(fork()==0)
{
int item;
while(1)
{
P(space);
P(mutex);
item=productItem();
*(buffer + sizeof(int)*i)=item;
i=(i+1)%N;
V(mutex);
V(products);
}
}
else
{
int item;
while(1)
{
P(products);
P(mutex);
item=*(buffer + sizeof(int)*j);
j=(j+1)%N;
consumeItem(item);
V(mutex);
V(space);
}
}
return 0;
}
信号量函数 semget() semop() semctl()相关推荐
- SystemV 信号量(一) —— SystemV信号量的相关操作函数(semget / semop /semctl)
SystemV IPC 方案的相关内容都是通过 "房间密码"来创建房间,获取到房间的ID,后面其他进程也可以根据这个房间密码来拿到同一个房间的ID.这是理解下面这些操作函数的关键. ...
- C语言sem Take函数,信号量函数sem.c
信号量函数sem.c 来源:华强电子网 作者:华仔 浏览:148 时间:2016-08-10 14:18 标签: 摘要: ;;; MantisOS中下信号量函数sem.c,主要调用了Linux底层的A ...
- 信号量 Linux函数 semget();semctl();semop();
Linux进程通信之信号量 信号量(semaphore)是变量,是一种特殊的变量.它紧取正值.对信息号量的操作只有2中: 等待(wait)和发送信号(signal). 信号量比较难理解.下面我们一个个 ...
- 系统编程04-消息队列(ftok、msgget、msgsnd、msgrcv、msgctl、shmget、shmat、shmdt、shmctl、semget、semctl、semop)
目录 一.linuxIPC对象 (Inter Process Communicate) 1.什么是IPC对象 1)想要操作文件(设备文件/dev): 2)想要操作消息队列: 2.查看系统中所有的IPC ...
- 十六:CreateSemaphore创建信号量,ReleaseSemaphore增加信号量 函数
在开发软件的过程中,多线程的程序往往需要实现相互通讯,比如几个线程添加一个消息到队列里,而另一个线程在睡眠时,就需要唤醒那个线程来处理事情.在这其中,就需要使用到信号量来进行同步.CreateSema ...
- Linux 3.进程间通信(shmget shmat shmdt shmctl 共享内存、signal signaction sigqueue 信号、semget semctl semop 信号量)
Linux 3.进程间通信(IPC) 共享内存 共享内存的接口指令 shmget 创建获取获取共享内存 shmat 映射:连接共享内存到当前进程的地址空间 shmdt 断开与共享内存的连接 shmct ...
- 专题 13 IPC之信号量
1.概述 信号量是一种计数器,用来控制对多个进程共享的资源所进行的访问.它们常被用做一个锁机制. 2.相关数据结构与函数 信号量数据结构: structsemun { intval;//当执行SETV ...
- linux系统调用函数---12
Linux应用编程学习笔记 周学伟 一.系统调用文件编程 1.文件打开函数 /*************************** ...
- linux 编程函数原型与用法
函数原型以及部分实例应用 --------------------------------------------------------------------------------------- ...
最新文章
- schema类SpringMVC+Hibernate+Spring整合(二)
- Angular 2 Output
- npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! test_vue_0613@1.0.0 dev: 错误的解决方法
- 2011年100佳精美的WordPress免费博客模板
- matlab和python哪个好学_python和matlab哪个难
- ^_^ 一看就忘不了的IE页面 ^_^
- 得到python默认的帮助文档
- 2022年后人工智能/深度学习八大应用方向
- 每个tabpage中都有一个dategridview_每个女人,都有一个礼服梦
- html访问java接口出现缓存_高可用架构设计(3) -电商商品详情页缓存背景及框架说明...
- 数据结构基础 后序遍历和中序遍历还原二叉树
- 尊重用户,提升产品欢迎度
- 图 邻接表 建立 深度遍历 广度遍历
- php end array_value,PHP常用处理数组函数
- DS博客大作业--树(李天明组)
- opencv摄像头拍摄视频并保存方法
- 全网首发:GB18030制定者站出来,$为什么要显示为¥,给大家解释一下
- 橙瓜发布2018网络小说风云榜年度榜,顶级大神作家的无声角逐
- 数学建模——模拟退火优化投影寻踪
- MySQL 日志的类型
热门文章
- Linux Shell函数返回值
- fatal error LNK1561: 必须定义入口点问题的我是这样解决的
- HDU - 7008 水题(打表)
- SDUT - Mountain Subsequences(dp)
- CodeForces - 1343F Restore the Permutation by Sorted Segments(思维)
- CodeForces - 1339D Edge Weight Assignment(思维)
- HYSBZ - 2342 双倍回文(回文自动机)
- 安川机器人焊枪切换设定方法_安川机器人参数更改方法
- 动态规划算法-02矿工挖矿问题
- 安装失败java.lang_linux安装jdk出现java/lang/NoClassDefFoundError: java/lang/Object错误的解决方案...