Linux进程间通信——使用信号量(转)
这篇文章将讲述别一种进程间通信的机制——信号量。注意请不要把它与之前所说的信号混淆起来,信号与信号量是不同的两种事物。有关信号的更多内容,可以阅读我的另一篇文章:Linux进程间通信——使用信号。下面就进入信号量的讲解。
- int semget(key_t key, int num_sems, int sem_flags);
- 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;
- };
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <sys/sem.h>
- union semun
- {
- int val;
- struct semid_ds *buf;
- unsigned short *arry;
- };
- static int sem_id = 0;
- static int set_semvalue();
- static void del_semvalue();
- static int semaphore_p();
- static int semaphore_v();
- int main(int argc, char *argv[])
- {
- char message = 'X';
- int i = 0;
- //创建信号量
- 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);
- }
- //设置要输出到屏幕中的信息,即其参数的第一个字符
- message = argv[1][0];
- sleep(2);
- }
- for(i = 0; i < 10; ++i)
- {
- //进入临界区
- if(!semaphore_p())
- exit(EXIT_FAILURE);
- //向屏幕中输出数据
- printf("%c", message);
- //清理缓冲区,然后休眠随机时间
- fflush(stdout);
- sleep(rand() % 3);
- //离开临界区前再一次向屏幕输出数据
- printf("%c", message);
- fflush(stdout);
- //离开临界区,休眠随机时间后继续循环
- if(!semaphore_v())
- exit(EXIT_FAILURE);
- sleep(rand() % 2);
- }
- sleep(10);
- printf("\n%d - finished\n", getpid());
- if(argc > 1)
- {
- //如果程序是第一次被调用,则在退出前删除信号量
- sleep(3);
- del_semvalue();
- }
- exit(EXIT_SUCCESS);
- }
- static int set_semvalue()
- {
- //用于初始化信号量,在使用信号量前必须这样做
- union semun sem_union;
- sem_union.val = 1;
- if(semctl(sem_id, 0, SETVAL, sem_union) == -1)
- return 0;
- return 1;
- }
- static void del_semvalue()
- {
- //删除信号量
- union semun sem_union;
- if(semctl(sem_id, 0, IPC_RMID, sem_union) == -1)
- fprintf(stderr, "Failed to delete semaphore\n");
- }
- static int semaphore_p()
- {
- //对信号量做减1操作,即等待P(sv)
- 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;
- }
- static int semaphore_v()
- {
- //这是一个释放操作,它使信号量变为可用,即发送信号V(sv)
- 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;
- }

- #include <stdio.h>
- #include <stdlib.h>
- int main(int argc, char *argv[])
- {
- char message = 'X';
- int i = 0;
- if(argc > 1)
- message = argv[1][0];
- for(i = 0; i < 10; ++i)
- {
- printf("%c", message);
- fflush(stdout);
- sleep(rand() % 3);
- printf("%c", message);
- fflush(stdout);
- sleep(rand() % 2);
- }
- sleep(10);
- printf("\n%d - finished\n", getpid());
- exit(EXIT_SUCCESS);
- }

Linux进程间通信——使用信号量(转)的更多相关文章
- Linux进程间通信——使用信号量
这篇文章将讲述别一种进程间通信的机制——信号量.注意请不要把它与之前所说的信号混淆起来,信号与信号量是不同的两种事物.有关信号的更多内容,可以阅读我的另一篇文章:Linux进程间通信——使用信号.下面 ...
- Linux进程间通信--使用信号量【转】
本文转载自:http://blog.csdn.net/ljianhui/article/details/10243617 这篇文章将讲述别一种进程间通信的机制——信号量.注意请不要把它与之前所说的信号 ...
- Linux进程间通信:管道,信号量,消息队列,信号,共享内存,套接字
Linux下的进程通信手段基本上是从UNIX平台上的进程通信手段继承而来的.而对UNIX发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间 ...
- Linux进程间通信——使用信号量【转】
本文转载自:http://blog.csdn.net/ljianhui/article/details/10243617 这篇文章将讲述别一种进程间通信的机制——信号量.注意请不要把它与之前所说的信号 ...
- Linux进程间通信之信号量
春节过去了,真的过去一年了.在公司待了快一年了.2016希望自己变得越来越好. ps:上面那句话是年前写的,中间隔了那么久,自己也变懒了. 一.信号量 1,信号量本质是一个计数器,控制访问共享资源的最 ...
- Linux -- 进程间通信之信号量
基本概念简述 多个线程同时访问一个共享数据,很可能造成恶劣的后果:为了保证数据访问资源的正确性和安全性,需要对线程进行"同步" (Linux下所有的执行实体都称为任务(task), ...
- Linux进程间通信(六):共享内存 shmget()、shmat()、shmdt()、shmctl()
下面将讲解进程间通信的另一种方式,使用共享内存. 一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式 ...
- Linux进程间通信——使用共享内存
一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式.不同进程之间共享的内存通常安排为同一段物理内存. ...
- Linux多线程--使用信号量同步线程【转】
本文转载自:http://blog.csdn.net/ljianhui/article/details/10813469 信号量.同步这些名词在进程间通信时就已经说过,在这里它们的意思是相同的,只不过 ...
随机推荐
- bzoj1618 / P2918 [USACO08NOV]买干草Buying Hay(完全背包)
P2918 [USACO08NOV]买干草Buying Hay 显然的完全背包 设$f[i]$为买$i$磅干草的最小代价 搞搞完全背包即可 注意到最后可能买的干草超出范围,但是价格可能更低. 于是我们 ...
- 20135320赵瀚青LINUX第四章读书笔记
概述 什么是进程调度 进程调度:在可运行态进程之间分配有限处理器时间资源的内核子系统. 一.调度策略 4.1进程类型 I/O消耗型进程:大部分时间用来提交I/O请求或是等待I/O请求,经常处于可运行状 ...
- Tomcat 发布项目 conf/Catalina/localhost 配置 及数据源配置
本文介绍通过在tomcat的conf/Catalina/localhost目录下添加配置文件,来发布项目.因为这样对 tomcat 的入侵性最小,只需要新增一个配置文件,不需要修改原有配置:而且支持动 ...
- sed删除包含指定字符串的所有行
1.以删除文件example.txt中包含字符串"=yes"的行为例,example.txt文件有以下内容: dadasdfsadf=yes=sds dsdadasdkfk dsd ...
- SDOI2018划水记
DAY -1 明天就要走了,今天就怎么也提不起兴趣来做题了.花了一个上午研究如何搞背景动画结果华丽丽失败了,为什么我自己设置的时候动画会在最上层啊(呜呜~~.下午随便打了板子又开始颓废了,然后看生蚝还 ...
- BloomFilter–大规模数据处理利器
转自: http://www.dbafree.net/?p=36 BloomFilter–大规模数据处理利器 Bloom Filter是由Bloom在1970年提出的一种多哈希函数映射的快速查找算法. ...
- 前端基础3:js篇(基础及算法)
1.js闭包相关: 题1: for (var i = 0; i < 5; i++) { setTimeout(function() { console.log(i); }, 1000 * i); ...
- ContentNegotiatingViewResolver多种输出格式实例: json/jsp/xml/xls/pdf
ContentNegotiatingViewResolver多种输出格式实例: json/jsp/xml/xls/pdf 本例用的是javaConfig配置 以pizza为例. json输出需要用到的 ...
- EF大数据批量添加性能问题
前几天做一个批量发消息的功能,因为要向消息表中批量写入数据,用的EF框架的插入方法:不用不知道,一用吓一跳:就10000条数据就耗时好几分钟,对应追求用户体验的我来说这是极不能容忍的,后来改为拼接SQ ...
- 表统计信息(storge)相关
select t1.NUM_ROWS,t1.BLOCKS,t1.EMPTY_BLOCKS,t1.AVG_SPACE,t1.CHAIN_CNT,t1.AVG_ROW_LEN from user_tab_ ...