https://www.cnblogs.com/LUO77/p/5816326.html
多进程:
首先,先来讲一下fork之后,发生了什么事情。
由fork创建的新进程被称为子进程(child process)。该函数被调用一次,但返回两次。两次返回的区别是子进程的返回值是0,而父进程的返回值则是新进程(子进程)的进程 id。将子进程id返回给父进程的理由是:因为一个进程的子进程可以多于一个,没有一个函数使一个进程可以获得其所有子进程的进程id。对子进程来说,之所以fork返回0给它,是因为它随时可以调用
getpid()来获取自己的pid;也可以调用getppid()来获取父进程的id。(进程id 0总是由交换进程使用,所以一个子进程的进程id不可能为0 )。
fork之后,操作系统会复制一个与父进程完全相同的子进程,虽说是父子关系,但是在操作系统看来,他们更像兄弟关系,这2个进程共享代码空间,但是数据空间是互相独立的,子进程数据空间中的内容是父进程的完整拷贝,指令指针也完全相同,子进程拥有父进程当前运行到的位置(两进程的程序计数器pc值相同,也就是说,子进程是从fork返回处开始执行的
),但有一点不同,如果fork成功,子进程中fork的返回值是0,父进程中fork的返回值是子进程的进程号,如果fork不成功,父进程会返回错误。
可以这样想象,2个进程一直同时运行,而且步调一致,在fork之后,他们分别作不同的工作,也就是分岔了。这也是fork为什么叫fork的原因
至于那一个最先运行,可能与操作系统(调度算法)有关,而且这个问题在实际应用中并不重要,如果需要父子进程协同,可以通过原语的办法解决。
常见的通信方式:
- 管道pipe:管道是一种
半双工
的通信方式,数据只能单向流动
,而且只能在具有亲缘关系的进程间
使用。进程的亲缘关系通常是指父子进程关系
。 - 命名管道FIFO:有名管道也是
半双工
的通信方式,但是它允许无亲缘关系进程间
的通信。 - 消息队列MessageQueue:消息队列是有
消息的链表
,存放在内核中并由消息队列标识符标识。消息队列克服了信号 传递信息少
、管道
只能承载无格式字节流
以及缓冲区大小受限
等缺点。 - 共享存储SharedMemory:共享内存就是映射一段能被其他进程所访问的内存,这段共享内存
由一个进程创建
,但多个进程都可以访问
。共享内存是最快的
IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量
,配合使用
,来实现进程间
的同步和通信
。 - 信号量Semaphore:信号量是一个
计数器
,可以用来控制多个进程对共享资源的访问
。它常作为一种锁机制
,防止某进程正在访问共享资源时,其他进程也访问该资源
。因此,主要作为进程间
以及同一进程内不同线程之间
的同步手段。 - 套接字Socket:套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。
- 信号 ( sinal ) : 信号是一种比较复杂的通信方式,
用于通知接收进程某个事件已经发生
。
进程间的通信方式–详细的请看原文