关于进程间通信的总结(IPC)
一:三个问题
进程间通信简单的说有三个问题。第一个问题是一个进程如何把信息传递给另一个。第二个要处理的问题是是,要确保两个或更多的的进程在关键互动中不会出现交叉(即是进程互斥的问题),第三个问题是与正确的顺序有关(即是进程之间的同步问题)。
二:信号量及PV操作
解决互斥进入临界区分为两种解决方案,软件解决方案和硬件解决方案,软件解决方案有Peterson解法,硬件解决方案有TSL指令, XCHG指令等。上述的解决方案都有忙等待的缺点,并且主要是用来解决互斥问题。
信号量是一种解决进程同步的解决方案,同时信号量也可以当作互斥量来使用。使用信号量来解决进程同步问题也是编程中使用较多的方法。使用信号量解决进程同步比较经典的问题是生产者消费者问题。Linux代码演示如下。
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <pthread.h>
- #include <semaphore.h>
- #include <signal.h>
- #define N 5 // 消费者或者生产者的数目
- #define M 10 // 缓冲数目
- //int M=10;
- int in = 0; // 生产者放置产品的位置
- int out = 0; // 消费者取产品的位置
- int buff[M] = { 0 }; // 缓冲初始化为0,开始时没有产品
- sem_t empty_sem; // 同步信号量,当满了时阻止生产者放产品
- sem_t full_sem; // 同步信号量,当没产品时阻止消费者消费
- pthread_mutex_t mutex; // 互斥信号量,一次只有一个线程访问缓冲
- int product_id = 0; //生产者id
- int prochase_id = 0; //消费者id
- //信号处理函数
- void Handlesignal(int signo){
- printf("程序退出%d\n",signo);
- exit(0);
- }
- /* 打印缓冲情况 */
- void print() {
- int i;
- printf("产品队列为");
- for(i = 0; i < M; i++)
- printf("%d", buff[i]);
- printf("\n");
- }
- /* 生产者方法 */
- void *product() {
- int id = ++product_id;
- while(1) {//重复进行
- //用sleep的数量可以调节生产和消费的速度,便于观察
- sleep(2);
- sem_wait(&empty_sem);
- pthread_mutex_lock(&mutex);
- in= in % M;
- printf("生产者%d在产品队列中放入第%d个产品\t",id, in);
- buff[in]= 1;
- print();
- ++in;
- pthread_mutex_unlock(&mutex);
- sem_post(&full_sem);
- }
- }
- /* 消费者方法 */
- void *prochase() {
- int id = ++prochase_id;
- while(1) {//重复进行
- //用sleep的数量可以调节生产和消费的速度,便于观察
- sleep(5);
- sem_wait(&full_sem);
- pthread_mutex_lock(&mutex);
- out= out % M;
- printf("消费者%d从产品队列中取出第%d个产品\t",id, out);
- buff[out]= 0;
- print();
- ++out;
- pthread_mutex_unlock(&mutex);
- sem_post(&empty_sem);
- }
- }
- int main() {
- printf("生产者和消费者数目都为5,产品缓冲为10,生产者每2秒生产一个产品,消费者每5秒消费一个产品,Ctrl+退出程序\n");
- pthread_t id1[N];
- pthread_t id2[N];
- int i;
- int ret[N];
- //结束程序
- if(signal(SIGINT,Handlesignal)==SIG_ERR){//按ctrl+C产生SIGINT信号
- printf("信号安装出错\n");
- }
- // 初始化同步信号量
- int ini1 = sem_init(&empty_sem, 0, M);//产品队列缓冲同步
- int ini2 = sem_init(&full_sem, 0, 0);//线程运行同步
- if(ini1 && ini2 != 0) {
- printf("信号量初始化失败!\n");
- exit(1);
- }
- //初始化互斥信号量
- int ini3 = pthread_mutex_init(&mutex, NULL);
- if(ini3 != 0) {
- printf("线程同步初始化失败!\n");
- exit(1);
- }
- // 创建N个生产者线程
- for(i = 0; i < N; i++) {
- ret[i]= pthread_create(&id1[i], NULL, product, (void *) (&i));
- if(ret[i] != 0) {
- printf("生产者%d线程创建失败!\n", i);
- exit(1);
- }
- }
- //创建N个消费者线程
- for(i = 0; i < N; i++) {
- ret[i]= pthread_create(&id2[i], NULL, prochase, NULL);
- if(ret[i] != 0) {
- printf("消费者%d线程创建失败!\n", i);
- exit(1);
- }
- }
- //等待线程销毁
- for(i = 0; i < N; i++) {
- pthread_join(id1[i], NULL);
- pthread_join(id2[i],NULL);
- }
- exit(0);
- }
在线程中也可以使用条件量解决生产者消费者问题,具体代码演示参考我的另一篇博客使用条件量解决生产者消费者问题。
三:管程
为了更易于编写正确的程序,Brinch Hansen (1973)和Hoare(1974)提出了一种高级同步原语,称为管程(monitor)。在下面的介绍中我们会发现,他们两人提出的方案略有不同。一个管程是一个由过程、变量及数据结构等组成的一个集合,它们组成一个特殊的模块或软件包。进程可在任何需要的时候调用管程中的过程,但它们不能在管程之外声明的过程中直接访问管程内的数据结构。C、C++不支持管程,Java语言支持管程。
四:其他通信方式
与管程和信号量有关的另一个问题是是,这些机制否是设计用来解决访问公共内存的一个或多个CPU上的互斥问题的。通过将信号量放在共享内存并用TSL或XCHG指令来保护他们,可以避免竞争。如果一个分布式系统具有多个CPU,并且每个CPU拥有自己的私有内存,他们通过一个局域网相连,那么这些源于将失效。这里的结论是信号量太低级,而管程在少数几个编程语言之外又无法使用,并且,这些源于均未提供机器见信息的交换方法。所以还需要其他办法。
1.消息传递
2.屏障
关于进程间通信的总结(IPC)的更多相关文章
- 四十九、进程间通信——System V IPC 之消息队列
49.1 System V IPC 介绍 49.1.1 System V IPC 概述 UNIX 系统存在信号.管道和命名管道等基本进程间通讯机制 System V 引入了三种高级进程间通信机制 消息 ...
- linux 进程间通信机制(IPC机制)一总览
1.作用:进程间通信机制(Inter Process Communication,IPC),这些IPC机制的存在使UNIX在进程通信领域手段相当丰富,也使得程序员在开发一个由多个进程协作的任务组成的系 ...
- 进程间通信之XSI IPC
XSI IPC源自于系统V的IPC功能. 有三种IPC我们称作XSI IPC,即消息队列.信号量以及共享存储器,它们之间有很多相似之处. 1.标识符和键 每个内核中的IPC结构(消息队列.信号量或共享 ...
- 五十、进程间通信——System V IPC 之共享内存
50.1 共享内存 50.1.1 共享内存的概念 共享内存区域是被多个进程共享的一部分物理内存 多个进程都可把该共享内存映射到自己的虚拟内存空间.所有用户空间的进程若要操作共享内存,都要将其映射到自己 ...
- linux 进程间通信机制(IPC机制)一消息队列
消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法.每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构.我们可以通过发送消息来避免命名管道的同步和阻塞问题.但是消息 ...
- 五十一、进程间通信——System V IPC 之进程信号量
51.1 进程信号量 51.1.1 信号量 本质上就是共享资源的数目,用来控制对共享资源的访问 用于进程间的互斥和同步 每种共享资源对应一个信号量,为了便于大量共享资源的操作引入了信号量集,可对所有信 ...
- linux 进程间通信机制(IPC机制)- 管道
一,定义: 管道又可以分为无名管道和命名管道,两者的用途是不一样的. 无名管道PIPE:主要用于具有亲缘关系的进程之间的通信,无名管道的通信是单向的,只能由一段到另外一段:无名管道是临时性的,完成通信 ...
- 【IPC第二个进程间通信】管道Pipe
IPC进程间通信+管道Pipe IPC(Inter-Process Communication,进程间通信). 管道用于进程间共享数据,事实上质是共享内存 ...
- 进程间通信 IPC(Inter-Process Communication)
目录 一.管道 二.FIFO 三.消息队列 四.信号量 五.共享存储 六.网络IPC:套接字 一.管道 管道是进程间通信中最古老的方式,所有UNIX都提供此种通信机制.管道有以下两种局限性: 历史 ...
- Windows下进程间通信及数据共享
进程是装入内存并准备执行的程序,每个进程都有私有的虚拟地址空间,由代码.数据以及它可利用的系统资源(如文件.管道等)组成. 多进程/多线程是Windows操作系统的一个基本特征.Microsoft W ...
随机推荐
- X64 Win7(win2008)连接SqlServer2005慢的解决办法
问题描述:数据库版本:SQL SERVER 2005数据库安装环境: Win 2003 X64 客户端环境:Win 2008 x64连接工具:ODBC或ado.net测试连接时间:4-6秒 客户端环境 ...
- Object-c中的属性和成员变量的关系详解
很多人在初学移动开发的时候会对object-c中的合成存取方法感到疑惑,此处尝试为看到本文有缘人答疑解惑,鄙人才疏学浅,难免有疏漏谬误之处,热烈欢迎诸位看官拍砖指点. 1.合成存取方法: OC为增加开 ...
- Android(java)学习笔记97:Scanner类使用
package cn.itcast_01; /* * Scanner:用于接收键盘录入数据. * * 前面的时候: * A:导包 * B:创建对象 * C:调用方法 * * System类下有一个静态 ...
- html/css 两个div在同一行
在界面设计的时候,经常需要将两个div在同一行显示. 但是每次都会忘记怎么做,特此随笔,备忘. 如以下要将“第一个div”和“第二个div”显示在同一行: <div id="id1&q ...
- linux【报错】userdel: user xiaoming is currently used by process 4713解决
学习linux的初学者肯定会遇到一些莫名其妙的问题,比如我,在学习删除一个用户的时候,就遇到上面的报错 userdel: user xiaoming is currently used by proc ...
- android 编写动画
1.在编写动画的时候需要新建一个xml 新建的步骤是选中res单击右键选择Android resource file 然后弹出一个框 ,然后再Resource Type 里面选择Animation 然 ...
- CSS: Float a div on another div, Ex: Text caption on picture
<style type="text/css"> .figure { width: 316px; height: 205px; display: block; borde ...
- Mac OS恢复出厂系统方法
1.重新启动时按住“Command()”和"R"键盘 2.选择磁盘工具
- 关于环信的WebIm的SDK一些使用注意
先打自己几下脸,不好好看接口文档,啪啪啪. 主要先说下回调,直接先copy文档的 conn.listen({ onOpened: function ( message ) { //连接成功回调 //以 ...
- MySQL多实例配置
实验环境:RHEL6.4为最小化安装,mysql安装包为通用二进制安装包,版本为mysql-5.6.26 创建mysql用户 #useradd –M –s /sbin/nologin mysql #y ...