进程间通讯有多种方式,包括信号,管道,消息队列,信号量,共享内存,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,信号)来主动发送信号

3.通过Queue

__author__ = 'lujianxing'
import threading
from time import sleep def f(q,t):
q.put(t) from multiprocessing import Process,Queue
if __name__ == '__main__':
q=Queue()
p = Process(target=f, args=(q,'ljx.sa'))
p.start()
p.join()
p1 = Process(target=f, args=(q,'ljx.elex'))
p1.start()
p1.join()
print q.qsize()

最新文章

  1. C++异常处理的问题
  2. Qt 二级菜单栏 中文无法输入问题
  3. 文本框不够长,显示“XXX...”
  4. 连接ssql语句
  5. Velocity语法大全
  6. phonegap 使用极光推送实现消息推送
  7. Spring学习总结一——SpringIOC容器一
  8. 3732 Ahui Writes Word
  9. ASP判断文件地址是否有效
  10. Linq保留字含义
  11. Luci流程分析(openwrt下)
  12. inner join on, left join on, right join on
  13. 矩阵[雅礼集训 2017 Day1]
  14. JavaWeb项目架构之NFS文件服务器
  15. html select 标签设置默认选中
  16. leetcode math类型题目解题总结
  17. pycharm设置文件编码
  18. java 实验 三 (2)(3)
  19. 20172306 2018-2019-2 《Java程序设计》第五周学习总结
  20. HTML中嵌套的子frame如何访问父页面中的函数?

热门文章

  1. Fast portable non-blocking network programming with Libevent--转
  2. 学通javaweb 24堂课 学习笔记
  3. Linux shell之数组
  4. Linux上安装Redmine
  5. DHCP 服务器
  6. windows7 图形界面远程 centos6.5
  7. jquery图片滑动联播效果
  8. [MSDN] 使用 SharePoint 2013 中的 JavaScript 库代码完成基本操作
  9. css3边框、阴影
  10. Smarty中一些标签的使用