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进程间通信--使用信号量【转】
		
本文转载自:http://blog.csdn.net/ljianhui/article/details/10243617 这篇文章将讲述别一种进程间通信的机制——信号量.注意请不要把它与之前所说的信号 ...
 - Linux进程间通信——使用信号量(转)
		
这篇文章将讲述别一种进程间通信的机制——信号量.注意请不要把它与之前所说的信号混淆起来,信号与信号量是不同的两种事物.有关信号的更多内容,可以阅读我的另一篇文章:Linux进程间通信——使用信号.下面 ...
 - 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 信号量.同步这些名词在进程间通信时就已经说过,在这里它们的意思是相同的,只不过 ...
 
随机推荐
- Eloquent ORM 之关联查询
			
小伙伴们好,本文是在我的前一篇随笔的基础上完成的,还没有浏览的同学,请移尊驾哦 Eloquent ORM学习笔记. 前一篇文章用到了leftJoin方法,其实Eloquent对于模块之间的关联查询有自 ...
 - android Xml生成一条细线,以及获取屏幕宽度和高度
			
<View android:layout_width="match_parent" android:layout_height="2dip" androi ...
 - QT Creator 2.7.2 代码自动补全快捷键设置
			
在QT Creater界面点[工具]再进[选项]找到[环境]下的[键盘]选项,搜索[CompleteThis]发现默认快捷键就是CTRL+SPACE,把它删除,然后添加自己想设置的快捷键(因为之前用e ...
 - :gAudit
			
http://www.doc88.com/p-0794369847693.html http://baike.baidu.com/link?url=pcOUfBpILuEAPFrBSsSU-6Vzg3 ...
 - Unix主机syslog配置
			
将下面的内容附加到/etc/syslog.conf文件中(注意*和@之间是有空格的): *.* @ip 修改/etc/services文件中的syslog服务的端口号为上面提到的Syslog监听端口. ...
 - jQuery提交form表单
			
<form id="search_form" name="search_form" method="post"> <inp ...
 - iOS7 UIKit动力学-碰撞特性UICollisionBehavior 下
			
上文讲到了为window加一个边界.实现碰撞的效果,接下来我们将提到一个托付方法: - (void)collisionBehavior:(UICollisionBehavior *)behavior ...
 - C# 泛型转换 将object[] 数组转换为泛型列表
			
public List<TaskSoftInfo> ReadSoftDownTaskList() { string[] Tid = (strin ...
 - ORACLE AUTOMATIC STORAGE MANAGEMENT翻译-第二章 ASM instance(1)
			
第二章 ASM INSTANCE ASM的类型,例如可以: 10g后ORACLE instance 类型增加了一个ASM种类.参数INSTANCE_TYPE=ASM进行设置. ASM实例启动命令: ...
 - Silverlight学习(五)图形标绘
			
Silverlight中进行图形标绘的方法太多了,这里的标绘和Arcgis中的标绘不同,这里大多是静态的标绘.标绘的方法主要有Path(路径标记法).直接标绘(Line等).几何标记(LineGeom ...