linux进程间通讯-System V IPC 信号量
进程间通信的机制——信号量。注意请不要把它与之前所说的信号混淆起来,信号与信号量是不同的两种事物。有关信号的很多其它内容,能够阅读我的还有一篇文章:Linux进程间通信——使用信号。以下就进入信号量的解说。
P操作 负责把当前进程由执行状态转换为堵塞状态,直到另外一个进程唤醒它。
操作为:申请一个空暇资源(把信号量减1),若成功,则退出;若失败,则该进程被堵塞;
V操作 负责把一个被堵塞的进程唤醒,它有一个參数表,存放着等待被唤醒的进程信息。
操作为:释放一个被占用的资源(把信号量加1),假设发现有被堵塞的进程,则选择一个唤醒之。
补充:查看共享信息的内存的命令是ipcs [-m|-s|-q] (所有的话是ipcs -a) ;查看共享信息的内存的命令是ipcs [-m|-s|-q]。
- int semget(key_t key, int num_sems, int sem_flags);
第一个參数key是整数值(唯一非零),不相关的进程能够通过它訪问一个信号量,它代表程序可能要使用的某个资源,程序对全部信号量的訪问都是间接的,程序先通过调用semget函数并提供一个键,再由系统生成一个对应的信号标识符(semget函数的返回值),仅仅有semget函数才直接使用信号量键,全部其它的信号量函数使用由semget函数返回的信号量标识符。假设多个程序使用同样的key值,key将负责协调工作。
- int semop(int sem_id, struct sembuf *sem_opa, size_t num_sem_ops);
- struct sembuf{
- short sem_num;//除非使用一组信号量,否则它为0
- short sem_op;//信号量在一次操作中须要改变的数据,一般是两个数,一个是-1,即P(等待)操作,
- //一个是+1,即V(发送信号)操作。
- short sem_flg;//通常为SEM_UNDO,使操作系统跟踪信号,
- //并在进程没有释放该信号量而终止时,操作系统释放信号量
- };
- int semctl(int sem_id, int sem_num, int command, ...);
- union semun{
- int val;
- struct semid_ds *buf;
- unsigned short *arry;
- };
- #if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
- /* union semun is defined by including <sys/sem.h> */
- #else
- /* according to X/OPEN we have to define it ourselves */
- union semun {
- int val; /* value for SETVAL */
- struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
- unsigned short int *array; /* array for GETALL, SETALL */
- struct seminfo *__buf; /* buffer for IPC_INFO */
- };
- #endif
- /* After the #includes, the function prototypes and the global variable, we come to the
- main function. There the semaphore is created with a call to semget, which returns the
- semaphore ID. If the program is the first to be called (i.e. it's called with a parameter
- and argc > 1), a call is made to set_semvalue to initialize the semaphore and op_char is
- set to X. */
- #include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <sys/sem.h>
- #include "semun.h"
- static int set_semvalue(void);
- static void del_semvalue(void);
- static int semaphore_p(void);
- static int semaphore_v(void);
- static int sem_id;
- int main(int argc, char *argv[])
- { int i;
- int pause_time;
- char op_char = 'O';
- srand((unsigned int)getpid());
- sem_id = semget((key_t)1234, 1, 0666 | IPC_CREAT);
- if (argc > 1) {
- if (!set_semvalue()) {
- fprintf(stderr, "Failed to initialize semaphore\n");
- exit(EXIT_FAILURE);
- }
- op_char = 'X';
- sleep(2);
- }
- /* Then we have a loop which enters and leaves the critical section ten times.
- There, we first make a call to semaphore_p which sets the semaphore to wait, as
- this program is about to enter the critical section. */
- for(i = 0; i < 10; i++) {
- if (!semaphore_p()) exit(EXIT_FAILURE);
- printf("%c", op_char);fflush(stdout);
- pause_time = rand() % 3;
- sleep(pause_time);
- printf("%c", op_char);fflush(stdout);
- /* After the critical section, we call semaphore_v, setting the semaphore available,
- before going through the for loop again after a random wait. After the loop, the call
- to del_semvalue is made to clean up the code. */
- if (!semaphore_v()) exit(EXIT_FAILURE);
- pause_time = rand() % 2;
- sleep(pause_time);
- }
- printf("\n%d - finished\n", getpid());
- if (argc > 1) {
- sleep(10);
- del_semvalue();
- }
- exit(EXIT_SUCCESS);
- }
- /* The function set_semvalue initializes the semaphore using the SETVAL command in a
- semctl call. We need to do this before we can use the semaphore. */
- static int set_semvalue(void)
- {
- union semun sem_union;
- sem_union.val = 1;
- if (semctl(sem_id, 0, SETVAL, sem_union) == -1) return(0);
- return(1);
- }
- /* The del_semvalue function has almost the same form, except the call to semctl uses
- the command IPC_RMID to remove the semaphore's ID. */
- static void del_semvalue(void){
- union semun sem_union;
- if (semctl(sem_id, 0, IPC_RMID, sem_union) == -1)
- fprintf(stderr, "Failed to delete semaphore\n");
- }
- /* semaphore_p changes the semaphore by -1 (waiting). */
- static int semaphore_p(void){
- struct sembuf sem_b;
- sem_b.sem_num = 0;
- sem_b.sem_op = -1; /* P() */
- sem_b.sem_flg = SEM_UNDO;
- if (semop(sem_id, &sem_b, 1) == -1) {
- fprintf(stderr, "semaphore_p failed\n");
- return(0);
- }
- return(1);
- }
- /* semaphore_v is similar except for setting the sem_op part of the sembuf structure to 1,
- so that the semaphore becomes available. */
- static int semaphore_v(void)
- {
- struct sembuf sem_b;
- sem_b.sem_num = 0;
- sem_b.sem_op = 1; /* V() */
- sem_b.sem_flg = SEM_UNDO;
- if (semop(sem_id, &sem_b, 1) == -1) {
- fprintf(stderr, "semaphore_v failed\n");
- return(0);
- }
- return(1);
- }
XX00XXOOXX00XXOOXX00XXOO……
linux进程间通讯-System V IPC 信号量的更多相关文章
- Linux 进程间通讯方式 pipe()函数 (转载)
转自:http://blog.csdn.net/ta893115871/article/details/7478779 Linux 进程间通讯方式有以下几种: 1->管道(pipe)和有名管道( ...
- Linux 进程间通讯
一.Linux 下进程间通讯方式 1)管道(Pipe)及有名管道(named pipe): 管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允 ...
- Linux进程通信之System V共享内存
前面已经介绍过了POSIX共享内存区,System V共享内存区在概念上类似POSIX共享内存区,POSIX共享内存区的使用是调用shm_open创建共享内存区后调用mmap进行内存区的映射,而Sys ...
- Linux进程通信之System V消息队列
System V消息队列是Open Group定义的XSI,不属于POSIX标准.System V IPC的历史相对很早,在上个世70年代后期有贝尔实验室的分支机构开发,80年代加入System V的 ...
- c#进程间通讯方案之IPC通道
转载:http://www.cnphp.info/csharp-ipc-channel-remoting.html 最近一直纠结与使用多进程还是多线程来构建程序.多线程的方法似乎不错,但是一个进程可承 ...
- Linux 进程间通讯详解一
进程间的通讯 两台主机间的进程通讯 --socket 一台主机间的进程通讯 --管道(匿名管道,有名管道) --System V进程间通信(IPC)包括System V消息队列,System V信号量 ...
- linux进程间通讯的几种方式的特点和优缺点
# 管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用.进程的亲缘关系通常是指父子进程关系.# 有名管道 (named pipe) : 有名管道也是 ...
- Linux 进程间通讯详解二
消息队列 --消息队列提供了本机上从一个进程向另外一个进程发送一块数据的方法 --每个数据块都被认为有一个类型,接收者进程接收的数据块可以有不同的类型值 --消息队列也有管道一样的不足,就是每个消息的 ...
- Linux进程间通讯的几种方式的特点和优缺点,和适用场合
http://blog.csdn.net/jeffcjl/article/details/5523569 由于不同的进程运行在各自不同的内存空间中.一方对于变量的修改另一方是无法感知的.因此.进程之间 ...
随机推荐
- nexus3添加第三方jar
最近在看maven的打包及管理,然後就看到nexus,自己在安裝的時候就下載了最新版的nexus-3.2.0-01-win64,按照文档部署后启动,浏览.之前一致使用的是2.0的,所以还是需要导出点点 ...
- CSS3------background-size(背景图片尺寸属性)
background-size 可以设置背景图片的大小,数值包括 长度length和百分比percentage. 并且会根据背景原点位置 background-origin 设置其图片覆盖的范围.那么 ...
- 定位 -CLGeocoder - 编码
#import "ViewController.h" #import <CoreLocation/CoreLocation.h> @interface ViewCont ...
- Pentaho Data Integration (三) Pan
官网连接: http://wiki.pentaho.com/display/EAI/Pan+User+Documentation Pan Pan 是一个可以执行使用Spoon编辑的transforma ...
- EXCEL : We can't do that to a merged cell.
- bzoj 3527: [Zjoi2014]力 快速傅里叶变换
题意: 给出n个数qi,给出Fj的定义如下: 令Ei=Fi/qi,求Ei. fft的那一堆东西还是背不到啊...这次写虽说完全自己写的,但是还是在参见了以前fft程序的情况下调了很久,主要在如下几点 ...
- MIME
http://www1.huachu.com.cn/read/readbookinfo.asp?sectionid=1000000558 http://www.jb51.net/hack/10623. ...
- 教你如何监控 Apache?
什么是 Apache? Apache 是一款 HTTP 服务器软件,现在更名为 "http",而 Apache 则成了一个(包含httpd的项目)巨大的基金组织,根据习惯后文都用 ...
- Hard Life
poj3155:http://poj.org/problem?id=3155 题意:最大密度子图的模板题. 题解:直接看代码. /* 题意简述一个公司有n个人,给出了一些有冲突的人的对数(u,v),所 ...
- ruby迭代器iterator和枚举器Enumerator
编写自定义的迭代器 The defining feature of an iterator method is that it invokes a block of code associatedwi ...