Linux进程和线程间IPC机制

转载 2018年04月16日 10:46:29

Linux进程间IPC

1.管道(Pipe)及有名管道(named pipe):

1、管道是半双工的,要实线读写需建立两根管道;
2、匿名管道用于父子进程或者兄弟进程之间(如forkexec创建的进程),命名管道允许没有亲缘关系的进程间通信;
3、单独构成一种独立的文件系统,它不是普通的文件,不属于某种文件系统,单独构成一种文件系统,并且只存在与内存中;
4、一个进程向管道中写的内容被管道另一端的进程读出。写内容每次都添加在管道缓冲区末尾,读每次从缓冲区头部读出数据。
5、管道的缓冲区是有限的(管道制存在于内存中,在管道创建时,为缓冲区分配一个页面大小);
6、管道所传送的是无格式字节流,这就要求管道的读出方和写入方必须事先约定好数据的格式。
7、管道只能在本地计算机中使用,而不可用于网络间的通信。
8、当写入数据量不大于PIPE_BUF时,linux将保证写入的原子性,当要写入数据量大于PIPE_BUF时,linux将不再保证写入的原子性。

2.信号(Signal):

信号机制是unix系统中最为古老的进程之间的通信机制,用于一个或几个进程之间传递异步信号。信号可以有各种异步事件产生,比如键盘中断等。shell也可以使用信号将作业控制命令传递给它的子进程。
int kill(pid_t pid,int sig); //kill函数向进程号为pid的进程发送信号

3.报文(Message)队列(消息队列):

1.msgqueue是内核地址空间中的内部链表,通过linux内核在各个进程传递内容,每个消息队列用IPC标识符唯一标识;
2.msgqueue可承载8192+4Bytes的格式化消息,与管道只能承载无格式字符流不同;
3.消息从末端加入,可依次出队也可按类型出队;
4.消息队列可独立于发送和接收进程存在,免去了同步命名管道打开和关闭时产生的麻烦;
5.同时通过发送消息还可以避免命名管道的同步和阻塞问题,不需要由进程自己来提供同步方法;

4.信号量(Semaphore):

主要作为进程间以及同一进程不同线程之间的同步手段。

5.共享内存(Memory Map)

共享内存是在多个进程之间共享内存区域的一种进程间的通信方式,由IPC为进程创建的一个特殊地址范围,它将出现在该进程的地址空间中.其他进程可以将同一段共享内存连接到自己的地址空间中.所有进程都可以访问共享内存中的地址,就好像它们是malloc分配的一样.如果一个进程向共享内存中写入了数据,所做的改动将立刻被其他进程看到。共享内存是IPC最快捷的方式,因为共享内存方式的通信没有中间过程,而管道、消息队列等方式则是需要将数据通过中间机制进行转换。共享内存方式直接将某段内存段进行映射,多个进程间的共享内存是同一块的物理空间,仅仅映射到各进程的地址不同而已,因此不需要进行复制,可以直接使用此段空间。

6.内存映射文件:

1、内存映射文件:
内存映射文件,是由一个文件到一块内存的映射。内存映射文件与虚拟内存有些类似,通过内存映射文件可以保留一个地址的区域,同时将物理存储器提交给此区域,内存文件映射的物理存储器来自一个已经存在于磁盘上的文件,而且对该文件进行操作之前必须先对文件进行映射。使用内存映射文件处理存储于磁盘上的文件时,不必再对文件执行I/O操作。每一个使用该机制进程通过把同一个共享文件映射到自己的进程地址空间来实现多个进程间的通信(这里类似于共享内存,只要有一个进程对这块映射文件的内存进行操作,其他进程也能够马上看到).
2.内存映身文件拷备效率:
使用内存映射文件不仅可以实现多个进程间的通信,还可以用于处理大文件提高效率。因为我们普通的做法是把磁盘上的文件先拷贝到内核空间的一个缓冲区再拷贝到用户空间(内存),用户修改后再将这些数据拷贝到缓冲区再拷贝到磁盘文件,一共四次拷贝。如果文件数据量很大,拷贝的开销是非常大的。那么问题来了,系统在在进行内存映射文件就不需要数据拷贝?mmap()确实没有进行数据拷贝,真正的拷贝是在在缺页中断处理时进行的,由于mmap()将文件直接映射到用户空间,所以中断处理函数根据这个映射关系,直接将文件从硬盘拷贝到用户空间,所以只进行一次数据拷贝。效率高于read/write。
3.共享内存和内存映射文件的区别:
内存映射文件是利用虚拟内存把文件映射到进程的地址空间中去,在此之后进程操作文件,就像操作进程空间里的地址一样了,比如使用c语言的memcpy等内存操作的函数.这种方法能够很好的应用在需要频繁处理一个文件或者是一个大文件的场合,这种方式处理IO效率比普通IO效率要高共享内存是内存映射文件的一种特殊情况,内存映射的是一块内存,而非磁盘上的文件。共享内存的主语是进程(Process),操作系统默认会给每一个进程分配一个内存空间,每一个进程只允许访问操作系统分配给它的哪一段内存,而不能访问其他进程的。而有时候需要在不同进程之间访问同一段内存,怎么办呢?操作系统给出了创建访问共享内存的API,需要共享内存的进程可以通过这一组定义好的API来访问多个进程之间共有的内存,各个进程访问这一段内存就像访问一个硬盘上的文件一样。

7.网络Socket/UNIX Domain Socket

socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket。虽然网络socket也可用于同一台主机的进程间通讯(通过loopback地址127.0.0.1),但是UNIX Domain Socket用于IPC更有效率:不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程。这是因为,IPC机制本质上是可靠的通讯,而网络协议是为不可靠的通讯设计的。UNIX Domain Socket也提供面向流和面向数据包两种API接口,类似于TCP和UDP,但是面向消息的UNIX Domain Socket也是可靠的,消息既不会丢失也不会顺序错乱。
  UNIX Domain Socket是全双工的,API接口语义丰富,相比其它IPC机制有明显的优越性,目前已成为使用最广泛的IPC机制,比如X Window服务器和GUI程序之间就是通过UNIX Domain Socket通讯的。
  使用UNIX Domain Socket的过程和网络socket十分相似,也要先调用socket()创建一个socket文件描述符,address family指定为AF_UNIX,type可以选择SOCK_DGRAM或SOCK_STREAM,protocol参数仍然指定为0即可。
  UNIX Domain Socket与网络socket编程最明显的不同在于地址格式不同,用结构体sockaddr_un表示,网络编程的socket地址是IP地址加端口号,而UNIX Domain Socket的地址是一个socket类型的文件在文件系统中的路径,这个socket文件由bind()调用创建,如果调用bind()时该文件已存在,则bind()错误返回。

8 消息总线(比如zeromq)

9 其他中间件(比如redis, memchache, 数据库等)

Linux线程间IPC

1 互斥锁

死锁的处理策略:
1、预防死锁:破坏死锁产生的四个条件:互斥条件、不剥夺条件、请求和保持条件以及循环等待条件。
2、避免死锁:在每次进行资源分配前,应该计算此次分配资源的安全性,如果此次资源分配不会导致系统进入不安全状态,那么将资源分配给进程,否则等待。算法:银行家算法。
3、检测死锁:检测到死锁后通过资源剥夺、撤销进程、进程回退等方法解除死锁。

2 读写锁
3 条件变量
4 信号量
5 自旋锁

自旋锁与互斥量类似,但它不是通过休眠使进程阻塞,而是在获取锁之前一直处于忙等(自旋)阻塞状态。自旋锁可以用于以下情况:锁被持有的时间短,而且线程并不希望在重新调度上花费太多的成本。

6 屏障

https://blog.csdn.net/a987073381/article/details/52029070

TCPIP

http://www.cnblogs.com/Jessy/p/3535612.html

Linux的进程和Win32的进程/线程比较

   熟悉WIN32编程的人一定知道,WIN32的进程管理方式与Linux上有着很大区别,在UNIX里,只有进程的概念,但在WIN32里却还有一个”线程”的概念,那么Linux和WIN32在这里究竟有着什么区别呢?
    WIN32里的进程/线程是继承自OS/2的。在WIN32里,”进程”是指一个程序,而”线程”是一个”进程”里的一个执行”线索”。从核心上讲, WIN32的多进程与Linux并无多大的区别,在WIN32里的线程才相当于Linux的进程,是一个实际正在执行的代码。但是,WIN32里同一个进 程里各个线程之间是共享数据段的。这才是与Linux的进程最大的不同。
   下面这段程序显示了WIN32下一个进程如何启动一个线程。

int g;
DWORD WINAPI ChildProcess( LPVOID lpParameter ){
int i;
for ( i = 1; i <1000; i ++) {
g ++;
printf( “This is Child Thread: %d/n”, g );
}
ExitThread( 0 );
};

void main()
{
int threadID;
int i;
g = 0;
CreateThread( NULL, 0, ChildProcess, NULL, 0, &threadID );
for ( i = 1; i <1000; i ++) {
g ++;
printf( “This is Parent Thread: %d/n”, g );
}
}

    在WIN32下,使用CreateThread函数创建线程,与Linux下创建进程不同,WIN32线程不是从创建处开始运行的,而是由 CreateThread指定一个函数,线程就从那个函数处开始运行。此程序同前面的UNIX程序一样,由两个线程各打印1000条信息。 threadID是子线程的线程号,另外,全局变量g是子线程与父线程共享的,这就是与Linux最大的不同之处。大家可以看出,WIN32的进程/线程 要比Linux复杂,在Linux要实现类似WIN32的线程并不难,只要fork以后,让子进程调用ThreadProc函数,并且为全局变量开设共享 数据区就行了,但在WIN32下就无法实现类似fork的功能了。所以现在WIN32下的C语言编译器所提供的库函数虽然已经能兼容大多数 Linux/UNIX的库函数,但却仍无法实现fork。
   对于多任务系统,共享数据区是必要的,但也是一个容易引起混乱的问题,在WIN32下,一个程序员很容易忘记线程之间的数据是共享的这一情况,一个线程修 改过一个变量后,另一个线程却又修改了它,结果引起程序出问题。但在Linux下,由于变量本来并不共享,而由程序员来显式地指定要共享的数据,使程序变 得更清晰与安全。
至于WIN32的”进程”概念,其含义则是”应用程序”,也就是相当于UNIX下的exec了。
   Linux也有自己的多线程函数pthread,它既不同于Linux的进程,也不同于WIN32下的进程,关于pthread的介绍和如何在Linux环境下编写多线程程序我们将在另一篇文章《Linux下的多线程编程》中讲述。

IPC进程之间通信的几种方式

进程间通信就是在不同进程之间传播或交换信息,那么不同进程之间存在着什么双方都可以访问的介质呢?进程的用户空间是互相独立的,一般而言是不能互相访问的,唯一的例外是共享内存区。但是,系统空间却是“公共场所...
  • lady_lili
  • lady_lili
  • 2016-09-22 16:41:06
  • 1749

Linux进程间通信_IPC机制

刚开始接触IPC机制时,感觉这个知识点真的时晦涩难懂,因此自己将自己对IPC机制的理解做下总结。 Linux中的IPC机制:信号量, 共享内存, 消息队列。 注意这里的IPC机制的通信只能在一台主机上...
  • xixihaha331
  • xixihaha331
  • 2016-05-16 18:03:23
  • 259

linux基础——linux进程间通信(IPC)机制总结

在linux下的多个进程间的通信机制叫做IPC(Inter-Process Communication),它是多个进程之间相互沟通的一种方法。在linux下有多种进程间通信的方法:半双工管道、命名管道...
  • a987073381
  • a987073381
  • 2016-07-23 21:33:12
  • 9156

进程间、线程间通信方式小结

之前一直对进程间和线程间的通信方式搞混,今天对它们总结一下。 一、进程间的通信方式 # 管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。...
  • Alexlee1986
  • Alexlee1986
  • 2014-03-14 10:40:04
  • 53486

Linux线程间同步机制_条件变量

有时看网上的博客自己会纳闷,进程间的同步机制和线程间的同步机制分别是什么?     其实进程之间是不用同步机制的,因为进程之间资源不共享,不需要同步机制来对所谓的临界资源进行保护,所以通常我们只讨论...
  • xixihaha331
  • xixihaha331
  • 2016-05-23 16:34:05
  • 1013

【Linux】进程间通信(IPC)之共享内存详解与测试用例

学习环境centos6.5 Linux内核2.6什么是共享内存共享内存允许两个或更多进程访问同一块内存。当一个进程改变了这块内存中的内容的的时候,其他进程都会察觉到这个更改。效率:因为所有进程共享同一...
  • a1414345
  • a1414345
  • 2017-04-06 14:54:54
  • 1238

进程ipc和线程通信

一、互斥与同步 1.互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。 2.同步:是指在互斥的基础上(大多数情况...
  • brandohero
  • brandohero
  • 2014-09-27 10:09:46
  • 436

进程间通信(IPC机制)精炼详解

一、前期基础知识储备IPC定义:IPC是intent-Process Communication的缩写,含义为进程间通信或者跨进程通信,是指两个进程之间进行数据交换的过程。IPC不是Android所独...
  • weixin_41101173
  • weixin_41101173
  • 2018-04-09 16:45:28
  • 128

线程间通信的几种方式

Java线程间通信: 1:线程上下文 2:共享内存 3:IPC通信 4:套接字(Socket),不同的机器之间进行通信 另外:附注通信内容: linux常用的进程间的通讯方式 (...
  • baidu_38376402
  • baidu_38376402
  • 2017-05-22 21:27:34
  • 1126

Linux进程间通信IPC的几种方式简介

Linux进程通信的源头       linux下的进程通信手段基本上是从Unix平台上的进程通信手段继承而来的。而对Unix发展做出重大贡献的两大主力AT&T(原为American Telephon...
  • u013074465
  • u013074465
  • 2015-05-27 19:58:11
  • 3867
收藏助手
不良信息举报
您举报文章:Linux进程和线程间IPC机制
举报原因:
原因补充:

(最多只允许输入30个字)