Python的进程间通信

进程间通讯有多种方式,包括信号,管道,消息队列,信号量,共享内存,socket等

1.共享内存

Python可以通过mmap模块实现进程之间的共享内存

mmap文件对象既像一个字符串也像一个普通文件对象。像字符串时因为我们可以改变其中的单个字符,如,obj[index] = ‘a‘,同时我们也可以改变一小段的字符,如 obj[2:5]=‘aaa‘。像文件对象是因为在mmap中会有操作标记,我们可以使用seek()方法来改变mmap对象的操作标记

mmap对象通过mmap()方法来构建,Windows系统和Unix系统下,构建方法是不同的。

window的构造方法:

class mmap.mmap(filenolength[, tagname[, access[, offset]]])

linux的构造方法:

class mmap.mmap(filenolength[, flags[, prot[, access[, offset]]]])

fileno是文件的标号,可以是普通的文件对象的标号,(文件对象通过fileno()方法获得),也可以是-1,-1代表这个内存是无名的。length参数定义该内存的长度,如果为0,就去fileno对应的文件的最大长度,access是改mmap对象的权限,可以是ACCESS_READ,ACCESS_WRITE ,ACCESS_COPY三个值,

linux中,

flags的值可以是MAP_PRIVATE 和MAP_SHARED ,默认是MAP_SHARED ,改参数用来标识改内存是私有的还是共享的

prot的值可以是PROT_READ 和PROT_WRITE,也是用来定义该mmap的权限的

flags+ prot 和access这种权限定义方式只能取一种,否则会报错

window中

tagname是这个mmap的标记,用来唯一标记这一块共享内存,作用像fileno

由于有tagname这个参数,所以在windows中,可以通过领fileno为-1,然后自定义一个tagname,例如‘mysharename’,来令多个进程都能共享同一块内存

但是在linux中,这种方法就不可以用了,只能通过打开一个文件,获取fileno来实现。

所以在window中,共享内存更加灵活

mmap对象常用的方法:

mmap.close() 关闭对象
mmap.find(string[, start[, end]])   在共享内存中查找内容,返回匹配内容最小的操作标记
mmap.flush([offset, size])  把内存的数据保存到硬盘中
mmap.move(dest, src, count) 移动操作标记
mmap.read(num)  从操作标记开始读取num个长度的字符
mmap.read_byte()  读取二进制数据
mmap.readline()   读取一行数据
mmap.resize(newsize)  修改mmap的长度
mmap.rfind(string[, start[, end]])   在共享内存中查找内容,返回匹配内容最大的操作标记
mmap.seek(pos[, whence])  移动操作标记
mmap.size()  返回mmap对象的长度
mmap.tell()  返回当前操作标记的位置
mmap.write(string)  写入内容.
mmap.write_byte(byte)  写入二进制内容

linux构造例子:

share_file=‘/tmp/mm.txt‘
f = open(share_file, ‘wb‘)
f.write(‘a‘ * share_size)
f.close()
f = open(share_file, ‘r+b‘)
mm = mmap.mmap(f.fileno(), 0)
f.close()

因为mmap对象的长度不能大于文件的长度,不然会报错:ValueError: mmap offset is greater than file siz

所以需要以wb的形式,先打开共享的文件,然后写入需要共享内存的长度的内容,关闭文件后以r+b方式打开文件,然后构造mmap对象。

当然,下次就可以直接用r+b的方式打开文件,然后构造对象了

参考:https://docs.python.org/2/library/mmap.html#module-mmap

2.信号

信号(signal)--     进程之间通讯的方式。一个进程一旦接收到信号就会打断原来的程序执行流程来处理信号。

几个常用信号:

SIGINT     终止进程  中断进程  (control+c)

SIGTERM   终止进程     软件终止信号

SIGKILL   终止进程     杀死进程

SIGALRM 闹钟信号

相对于共享内存,信号更加偏向于系统层面的,linux系统也是通过信号来管理进程,而且系统也规定了某些进程接到某些信号后的行为。

当然我们可以通过绑定信号处理函数来修改进程收到信号以后的行为

#encoding=utf-8
import os
import signal
from time import sleep
def my_term(a,b):
    print "收到sigterm信号"
signal.signal(signal.SIGTERM,my_term)
def my_usr1(a,b):
    print "收到SIGUSR1信号"
signal.signal(signal.SIGUSR1,my_usr1)
while 1:
    print "我是进程id是",os.getpid()
    sleep(1)

可以通过os.kill(pid,信号)来主动发送信号

Python的进程间通信,布布扣,bubuko.com

时间: 2024-08-05 09:24:01

Python的进程间通信的相关文章

Python、进程间通信、进程池、协程

进程间通信 进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的. 进程队列queue 不同于线程queue,进程queue的生成是用multiprocessing模块生成的. 在生成子进程的时候,会将代码拷贝到子进程中执行一遍,及子进程拥有和主进程内容一样的不同的名称空间. 示例1: 1 import multiprocessing 2 def foo(): 3 q.put([11,'hello',True]

python多进程——进程间通信

(一)进程锁 抢票的例子: # -*- coding:utf-8 -*- from multiprocessing import Process, Lock import time import json count = {'count': 1} # 仅剩最后一张票 with open('db.txt', 'w', encoding='utf-8') as f: json.dump(count, f) # 返回剩余票数 def search(): dic = json.load(open('db

Python开发基础--- 进程间通信、进程池、协程

进程间通信 进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的. 进程队列queue 不同于线程queue,进程queue的生成是用multiprocessing模块生成的. 在生成子进程的时候,会将代码拷贝到子进程中执行一遍,及子进程拥有和主进程内容一样的不同的名称空间. 示例1: 1 import multiprocessing 2 def foo(): 3 q.put([11,'hello',True]

python基础之进程间通信、进程池、协程

进程间通信 进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的. 进程队列queue 不同于线程queue,进程queue的生成是用multiprocessing模块生成的. 在生成子进程的时候,会将代码拷贝到子进程中执行一遍,及子进程拥有和主进程内容一样的不同的名称空间. 示例1: 1 import multiprocessing 2 def foo(): 3 q.put([11,'hello',True]

python MultiProcessing模块进程间通信的解惑与回顾

这段时间沉迷MultiProcessing模块不能自拔,没办法,python的基础不太熟,因此就是在不断地遇到问题解决问题.之前学习asyncio模块学的一知半解,后来想起MultiProcessing模块更是一知半解,趁着暑假无聊就研究了一下,不得不说,这加深了自己对Python基础的掌握与理解...于是就有了这一系列<python标准库之MultiProcessing库的研究 (1)><python MultiProcessing标准库使用Queue通信的注意要点><py

python并发编程之多进程(二):互斥锁(同步锁)&amp;进程其他属性&amp;进程间通信(queue)&amp;生产者消费者模型

一,互斥锁,同步锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 竞争带来的结果就是错乱,如何控制,就是加锁处理 part1:多个进程共享同一打印终端 #并发运行,效率高,但竞争同一打印终端,带来了打印错乱 from multiprocessing import Process import os,time def work(): print('%s is running' %os.getpid()) time.sleep(2) print('

资深程序员:深入Python进程间通信原理!

输出 3.14159262176 管道pipe 管道是Unix进程间通信最常用的方法之一,它通过在父子进程之间开通读写通道来进行双工交流.我们通过os.read()和os.write()来对文件描述符进行读写操作,使用os.close()关闭描述符. 上图为单进程的管道 上图为父子进程分离后的管道 输出 3.14159262176 无名套接字socketpair 我们知道跨网络通信免不了要通过套接字进行通信,但是本例的多进程是在同一个机器上,用不着跨网络,使用普通套接字进行通信有点浪费. 上图为

python 进程间通信

Python进程.进程池以及进程间通信 进程间通信的几种方式 python进程间通信:Queue pipe 原文地址:https://www.cnblogs.com/charlieLeo/p/9544145.html

python 进程 进程池 进程间通信

1.python 中创建进程的两种方式: from multiprocessing import Process import time def test_(): print '-----test-----' if __name__ == '__main__': p = Process(target=test_) p.start() while True: print '--main--' '''1.通过process 类创建一个进程对象,然后start即可开启进程, test test_函数是