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 ...
随机推荐
- maven课程 项目管理利器-maven 5-1 课程总结 1星(2018-11-08 07:19)
1 maven windows环境搭建和配置环境变量 2 maven骨架和pom.xml 解析 3 命令行窗口常用的maven命令 4 仓库和坐标 5 maven Java项目 6 生命周期,依赖聚合 ...
- 设置 text-align: center;line-height:height 居中无效
1.设置文字水平居中 内联元素(行内元素)使用: text-align: center: 使用后文字仍然没有居中 解决方法:设置width:100%: 块元素使用: margin: 0 auto; 2 ...
- 转:ArcGIS10.1正式版安装与破解
一.准备文件 ArcGIS10.1安装包:ArcGIS_Desktop_10.1_129026(en) 认证服务:Pre-release_license_manager 注册机:arcgis10.1K ...
- C++ Knowledge series Inheritance & RTTI & Exception Handling
Inheritance The pointer or reference to base class can address/be assigned with any of the classes d ...
- EditText中光标的位置设置
CharSequence text = userName.getText(); if (text instanceof Spannable) { ...
- 用Android studio进行 OpenCV 开发的第一个项目
我的天! 折腾了好久终于搭建成功了第一个项目. 项目环境: Windows 7 家庭普通版 64位 Android studio 1.5.1 OpenCV-2.4.9-android-sdk 基于 ...
- Struts2_Struts标签
1.property <s:property value="username" /> 一般访问,访问ValueStack中的第一个username <s:prop ...
- Active Directory域服务备份
此篇介绍如何通过Windows Server Backup工具备份Active Directory域服务 AD 域系统状态 在域控制器上,系统状态通常包括以下内容,但所包含的数据实际上取决于服务器上安 ...
- oracle11g在CentOS6.9上启动脚本
#!/bin/bash# chkconfig:2345 99 10# description: Startup Script for oracle Database# /etc/init.d/orac ...
- ffmpeg处理RTMP流媒体的命令大全
最近浏览国外网站时候发现,翻译不准确的敬请谅解. 1.将文件当做直播送至live ffmpeg -re -i localFile.mp4 -c copy -f flv rtmp://server/li ...