linux ipc信号量
ipcs 命令,可以看到当前系统上的共享资源实例
ipcrm 命令,可以删除一个共享资源实例
linux 操作信号量的函数有三个:semget, semop, semctl
semget 声明为:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h> int semget(key_t key, int nsems, int semflg);
key 是一个键值,用来标识一个全局唯一的信号量集。要通过信号量通信的进程需要使用相同的键值来获取该信号量。
nsems 表示要创建/获取的信号量集中信号量的数目。如果是创建信号量,这个值必须指定。如果是获取已经存在的信号量,可以把它设置成0.
semflg 指定一组标志。它的低端9个比特是该信号量的权限。相当于文件操作权限,类似open函数的mode参数。而且,它还可以和IPC_CREAT标志按位“或”运算来创建新的信号量集。
成功返回一个正整数,它是信号量集的标识符;失败返回-1,并设置errno
semop 系统调用改变信号量的值,即执行P、V操作:
int semop(int semid, struct sembuf *sops, size_t nsops);
semid 是由 semget 返回的信号量集标识符,用来指定被操作的目标信号量集。
sops 是 struct sembug 结构体,定义为:
/* Structure used for argument to `semop' to describe operations. */
struct sembuf
{
unsigned short int sem_num; /* semaphore number */
short int sem_op; /* semaphore operation */
short int sem_flg; /* operation flag */
};
sem_num 是信号量集的编号,0表示第一个信号量。
sem_op 指定操作类型,可选值为正整数、0、负整数。
sem_flg 可选值是 IPC_NOWAIT, SEM_UNDO。IPC_NOWAIT指,无论信号量集操作是否成功,semop调用都立刻返回。SEM_UNDO含义是,当进程退出时,取消正在进行的semop操作
nsops参数指定要执行的操作个数,即sops数组中元素的个数。semop对数组sops中的每个元素按照数组顺序依次执行操作,并且这个过程是原子操作。
semop成功返回0,失败返回-1并设置errno。失败的时候,sops数组中指定的所有操作都不执行。
semctl用来对信号量进行直接操作:
int semctl(int semid, int semnum, int cmd, ...);
semid 是semget调用返回的信号量集标识符。semnum指定被操作的信号量在信号量集中的编号。cmd指定要执行的命令。有的命令需要传入第4个参数,这个参数类型由用户定义,但是,内核给出了它的格式,而且,必须是这个格式:
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux-specific) */
};
cmd 的值比较多,不列举了,可以看manpage,其中,
IPC_STAT 将信号量集关联的内核数据结构复制到semun.buf中,
GETVAL 获取信号量的semval的值
SETVAL 将信号量的semval值设置为semun.val
IPC_RMID 立即移除信号量集,唤醒所有等待信号量集的进程
该函数返回值根据cmd不同而不同。失败返回-1,并设置errno
semget函数第一个参数key可以设置为 IPC_PRIVATE(值为0),这样,无论信号量是否存在,都会创建一个新的信号量
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/wait.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 */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux-specific) */
}; void ErrExit(const char* reason)
{
fprintf(stderr, "%s: %d, %s\n", reason, errno, strerror(errno));
exit();
} int initsem(int key = )
{
int semid = -;
if (- == (semid = semget(key, , | IPC_CREAT)))
{
ErrExit("semget");
} // 信号量初始值为1
union semun sem_un;
sem_un.val = ;
if (- == semctl(semid, , SETVAL, sem_un))
{
ErrExit("semctl");
} return semid;
} void destroysem(int semid)
{
if (- == semctl(semid, , IPC_RMID))
{
ErrExit("semctl del");
}
} // -1 为 p 操作
void P(int semid)
{
struct sembuf op;
op.sem_num = ;
op.sem_op = -;
op.sem_flg = SEM_UNDO;
if (- == semop(semid, &op, ))
{
ErrExit("semop p");
}
} // 1 为 v 操作
void V(int semid)
{
struct sembuf op;
op.sem_num = ;
op.sem_op = ;
op.sem_flg = SEM_UNDO;
if (- == semop(semid, &op, ))
{
ErrExit("semop v");
}
} int main(int argc, char const *argv[])
{
int semid = initsem();
pid_t pid = fork(); if (pid > )
{
P(semid);
printf("in parent process...\n");
sleep();
V(semid); waitpid(pid, NULL, );
// 删除信号量集
destroysem(semid);
}
else if ( == pid)
{
P(semid);
printf("in child process...\n");
sleep();
V(semid);
}
else
{
ErrExit("fork");
} return ;
}
linux ipc信号量的更多相关文章
- linux进程间通讯-System V IPC 信号量
进程间通信的机制--信号量.注意请不要把它与之前所说的信号混淆起来,信号与信号量是不同的两种事物.有关信号的很多其它内容,能够阅读我的还有一篇文章:Linux进程间通信--使用信号.以下就进入信号量的 ...
- 【linux】系统编程-3-system-V IPC 信号量
目录 前言 5. 信号量 5.1 概念 5.2 工作原理 5.3 操作函数 5.3.1 semget() 5.3.2 semop() 5.3.3 semctl() 5.4 例程 参考: 前言 原文链接 ...
- linux进程间通信-信号量(semaphore)
一 为什么要使用信号量 为了防止出现因多个程序同时访问一个共享资源而引发的一系列问题,我们需要一种方法,它可以通过生成并使用令牌来授权,在任一时刻只能有一个执行线程访问 代码的临界区域.临界区域是指执 ...
- Linux IPC实践(1) -- 概述
进程的同步与互斥 进程同步: 多个进程需要相互配合共同完成一项任务. 进程互斥: 由于各进程要求共享资源,而且有些资源需要互斥使用,因此各进程间竞争使用这些资源,进程的这种关系为进程的互斥;系统中某些 ...
- linux ipc/its
linux进程间双向消息队列 server.c #include <stdio.h> #include <stdlib.h> #include <string.h> ...
- Linux IPC之共享内存C 事例
Linux IPC之共享内存 标签: linuxrandomnull工作 2011-08-25 11:52 4123人阅读 评论(0) 收藏 举报 分类: Linux(3) 读书札记(3) 版权 ...
- IPC——信号量
Linux进程间通信——使用信号量 这篇文章将讲述别一种进程间通信的机制——信号量.注意请不要把它与之前所说的信号混淆起来,信号与信号量是不同的两种事物.有关信号的更多内容,可以阅读我的另一篇文章:L ...
- Linux进程间通信--信号量
信号量绝对不同于信号,一定要分清,关于信号,上一篇博客中已经说过,如有疑问,请移驾! 信号量 一.是什么 信号量的本质是一种数据操作锁,它本身不具有数据交换的功能,而是通过控制其他的通信资源(文件 ...
- Linux有名信号量的创建(sem_open中name参数构造)【转】
转自:http://blog.csdn.net/gfeng168/article/details/40740865 版权声明:本文为博主原创文章,未经博主允许不得转载. 一.sem_open函数nam ...
随机推荐
- 国内外著名B2C系统介绍兼比较【收藏版】
一.国内知名B2C系统 1.Shopex国内最大的电子商务系统,有各种辅助工具,php开发,免费但不开源,网店模板众多,较适合有淘宝店的卖家.网址:www.shopex.cn 2.ECshop免费且开 ...
- spring-boot学习之属性配置
通过@value注解,将配置文件中的内容引入
- 微信小程序实战篇:商品属性联动选择(案例)
本期的微信小程序实战篇来做一个电商网站经常用到的-商品属性联动选择的效果,素材参考了一点点奶茶. 效果演示: 商品属性联动.gif 代码示例 1.commodity.xml <!-- < ...
- React 复合组件
var Avatar = React.createClass({ render: function() { return ( <div> <ProfilePic username={ ...
- 将pugixml库编译成动态库的做法
作者:朱金灿 来源:http://blog.csdn.net/clever101 pugixml库默认是编译成静态库的.要把pugixml库编译成一个动态库,需要对代码做一些修改,具体是将 // If ...
- 转:Windows任务计划实现自动执行ArcGIS相关功能
今天一不小心点开了Windows任务计划,以前咩有怎么用过,发现还挺好用,于是想到了以前用户的一些问题 1:用户环境使用ArcSDE服务连接,每次运行到一定的负载量(可能是几天),就会很慢,用户就喜欢 ...
- 如何领域驱动设计?-实践感悟&总结分享
主要是在开发过程中,个人对于领域驱动设计的实践感悟和总结:也是对新进开发人员的培训资料:希望对关注DDD的童鞋有所帮助. 概述 领域驱动不是纯粹的技术问题,领域建模(建立数据表只是一部分)是领域专家( ...
- java:Java环境配置
1.安装JDK开发环境 下载网站:http://www.oracle.com/ 2.配置环境变量: 对于Java程序开发而言,主要会使用JDK的两个命令:javac.exe.java.exe.路径:C ...
- Java线程堆栈分析
不知觉间工作已有一年了,闲下来的时候总会思考下,作为一名Java程序员,不能一直停留在开发业务使用框架上面.老话说得好,机会是留给有准备的人的,因此,开始计划看一些Java底层一点的东西,尝试开始在学 ...
- C#学习基础,面向对象的三大特征
学习C#编程,相信大家除了经常接触的是hello world之外,更多的是进一步的去熟悉这门语言的基本特征,以及有哪些概念是我们必要掌握了解的,相信大家都是会知道面向对象的三大特性分别是:封装,继承, ...