1.进程间通信方式
套接字、信号、匿名管道、命名管道、共享内存和全局对象、队列和子类
2.管道
管道是Linux由Unix那里继承过来的进程间的通信机制,它是Unix早期的一个重要通信机制。
其思想是,在内存中创建一个共享文件,从而使通信双方利用这个共享文件来传递信息。
由于这种方式具有单向传递数据的特点,所以这个作为传递消息的共享文件就叫做“管道”。
3.匿名管道
概览
由父进程创建的子进程将会赋值父进程包括文件在内的一些资源。如果父进程创建子进程之前创建了一个文件,那么这个文件的描述符就会被父进程在随后所创建的子进程所共享。
也就是说,父、子进程可以通过这个文件进行通信。
如果通信的双方一方只能进行读操作,而另一方只能进行写操作,那么这个文件就是一个只能单方向传送消息的管道。如下图所示:
基本操作
''' 1.子进程通过os.write -> 管道 -> 父进程 2.父进程os.read()会等待子进程在管道上发送数据(阻塞) ''' import os,sys,time def child(pw): time.sleep(5) msg='child processing' os.write(pw,msg.encode()) #将msg写入文件描述符pw def parent(): r,w = os.pipe() if os.fork() == 0: #child processing child(w) else: msg = os.read(r,32) #主线程监听管道,每次有数据则继续执行 print(msg) parent()
双向匿名管道
...
multiprocessing模块的管道
''' 1.multiprocessing的管道默认是双向的 ''' import os from multiprocessing import Process,Pipe def sender(pipe): #单工 pipe.send('i,am a child(sender)') pipe.close() def talker(pipe): #双工 pipe.send('i,am a child(talker)') #向父进程发送消息 (子->父) res= pipe.recv() #获得父进程的回复消息 (父->子) print('msg from parent: ' + res) if __name__=='__main__': #单工模式 parentEnd,childEnd = Pipe() p = Process(target = sender,args=(childEnd,)) p.start() print('msg from child(sender): '+ parentEnd.recv()) parentEnd.close() #双工模式 parentEnd,childEnd = Pipe() c = Process(target = talker,args=(childEnd,)) c.start() print('msg from child(talker)' + parentEnd.recv()) parentEnd.send('i,am a parent response') c.join() #等待子进程执行完毕,否则后面的打印可能会出现在不可预料的地方 print('end')
4.命名管道
...
5.套接字
概述
源IP地址和目的IP地址以及源端口号和目的端口号的组合称为套接字。
套接字,是支持TCP/IP的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定
基本操作
''' 1.程序实现了服务端功能、客户端 2.在一个新线程里面启动服务端 3.在另外5个线程里面运行客户端 ''' from socket import socket , AF_INET,SOCK_STREAM port = 50008 host='localhost' def server(): sock = socket(AF_INET,SOCK_STREAM) sock.bind(('',port)) sock.listen(5) while True: conn,addr=sock.accept() #产生阻塞,直到有新的连接 data = conn.recv(1024) reply = 'server got :[%s]' % data conn.send(reply.encode()) def client(name): sock = socket(AF_INET,SOCK_STREAM) sock.connect((host,port)) sock.send(name.encode()) reply = sock.recv(1024) sock.close() print('client got :[%s]' % reply) if __name__ == '__main__': from threading import Thread sthread = Thread(target = server) sthread.daemon = True sthread.start() print('server start') for i in range(5): Thread(target=client,args=('client%s' % i,)).start()
6.信号
7.共享内存和全局对象
8.队列和子类
参考: