关于进程间通信的总结(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 ...
随机推荐
- oracle internal :VIEW: X$KCBLDRHIST - Direct Read HISTory
WebIV:View NOTE:159900.1 Note (Sure) - Note Mods - Note Refs Error ORA 600 TAR TAR-Info Bug B ...
- Github上最全的APICloud开源前端框架效果盘点(转)
1.微信网站几分钟变身“原生 App” 微信推出了微信JS-SDK,使微信公共号可以直接调用微信原生的接口,具备部分原生应用的能力.微信JS-SDK的推出,将大大提高微信公共号的 用户体验,但是如果存 ...
- [MODX] 0. Mangement System Overview
In Modex, there are three tabs: Resoources, Elements & Files First: 'Files' is the place where t ...
- mysql颠覆实战笔记(二)-- 用户登录(一):唯一索引的妙用
版权声明:笔记整理者亡命小卒热爱自由,崇尚分享.但是本笔记源自www.jtthink.com(程序员在囧途)沈逸老师的<web级mysql颠覆实战课程 >.如需转载请尊重老师劳动,保留沈逸 ...
- ORACLE 导入导出操作
1.导入命令: imp userId/psw@orcl full=y file=D:\data\xxx.dmp ignore=y 2.导出命令 exp userId/psw@orcl file=d: ...
- 进程间通信之管道(pipe、fifo)
我们先来说说进程间通信(IPC)的一般目的,大概有数据传输.共享数据.通知事件.资源共享和进程控制等.但是我们知道,对于每一个进程来说这个进程看到属于它的一块内存资源,这块资源是它所独占的,所以进程之 ...
- coherence配置说明
经过上篇 coherence初识 ,最近算是和coherence杠上了,针对coherence3.5.3这个版本,把学到的东西整理下 1. 这个jar包有点大,4M多,首先打开coherence.ja ...
- Adobe Edge Animate –使用css制作菜单
Adobe Edge Animate –使用css制作菜单 版权声明: 本文版权属于 北京联友天下科技发展有限公司. 转载的时候请注明版权和原文地址. 效果图:
- POJ 3253 Fence Repair (贪心)
Fence Repair Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit ...
- VC操作Excel之基本操作
// 变量的定义 _Application app; Workbooks books; _Workbook book; Worksheets sheets; _Worksheet sheet; Ran ...