LinuxIPC通信之Pipe(C+Python实现)
进程通信是指在进程间传输数据(交换信息)。进程通信根据交换信息量的多少和效率的高低,分为低级通信(只能传递状态和整数值)和高级通信(提高信号通信的效率,传递大量数据,减轻程序编制的复杂度)。其中高级进程通信分为三种方式:共享内存模式、消息传递模式、共享文件模式。
在别人博客看到的这段话,也不知道那个抄那个的哈哈
linux下的进程通信手段基本上是从Unix平台上的进程通信手段继承而来的。而对Unix发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间通信方面的侧重点有所不同。前者对Unix早期的进程间通信手段进行了系统的改进和扩充,形成了“system V IPC”,通信进程局限在单个计算机内;后者则跳过了该限制,形成了基于套接口(socket)的进程间通信机制。
常见的通信方式:
1. 管道pipe:管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
2. 命名管道FIFO:有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
4. 消息队列MessageQueue:消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
5. 共享存储SharedMemory:共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。
6. 信号量Semaphore:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
7. 套接字Socket:套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。
8. 信号 ( sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
第一篇首先来实现pipe通信
匿名管道:
- 只能用于具有血缘关系的进程之间通信
- 生命周期随进程,进程退出,管道释放
- 管道是半双工的,数据只能从一个方向传输
- 管道是基于字节流的
- 管道是自带同步机制的,在保证数据安全的前提下,按照特定顺序访问临界资源
python:
函数说明:
multiprocessing.Pipe([duplex]) 返回2个连接对象(conn1, conn2),代表管道的两端,默认是双向通信.
如果duplex=False,conn1只能用来接收消息,conn2只能用来发送消息.不同于os.open之处在于os.pipe()返回2个文件描述符(r, w),表示可读的和可写的
多进程 Multiprocessing 模块
Process 类
Process 类用来描述一个进程对象。创建子进程的时候,只需要传入一个执行函数和函数的参数即可完成 Process 示例的创建。
star() 方法启动进程,
join() 方法实现进程间的同步,等待所有进程退出。
close() 用来阻止多余的进程涌入进程池 Pool 造成进程阻塞。
multiprocessing.Process(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)
target 是函数名字,需要调用的函数
args 函数需要的参数,以 tuple 的形式传入
#!/usr/bin/python3
import multiprocessing
arron_say=('1','3','5','7','9')
kobe_say=('2','4','6','8','10')
def arron_handler(read_fd,write_fd):
for str in kobe_say:
print("kobe say:>%s"%read_fd.recv())
write_fd.send(str)
def kobe_handler(read_fd,write_fd):
for str in arron_say:
write_fd.send(str)
print("arron say:>%s"%read_fd.recv())
(read_fd1,write_fd1) = multiprocessing.Pipe()
(read_fd2,write_fd2) = multiprocessing.Pipe()
arron = multiprocessing.Process(target=arron_handler,args=(read_fd1,write_fd2))
arron.start()
kobe_handler(read_fd2,write_fd1)
#arron.start()
read_fd1.close()
read_fd2.close()
write_fd1.close()
write_fd2.close()
arron.join()
C:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
int main(int argc, char **argv)
{
int fd[2];
if(pipe(fd) == -1)
{
perror("pipe()");
exit(1);
}
pid_t x = fork();
if(x == 0)
{
char *s = "hello, I am your child\n";
write(fd[1], s, strlen(s));
}
if(x > 0)
{
char buf[30];
bzero(buf, 30);
read(fd[0], buf, 30);
printf("from child: %s", buf);
}
close(fd[0]);
close(fd[1]);
return 0;
}