Python之路PythonThread,第三篇,进程3
python3 进程3
管道
在内存中开辟一个管道空间,对多个进程可见。 在通信形式上形成一种约束;
linux 文件类型
b c d - l s p
目录 普通文件 链接 套接字 管道
multiprocessing -----> Pipe函数
Pipe(duplex)
功能:创建一个管道
参数:duplex 默认为True 表示管道为双向管道(全双工);
如果设置为False, 则表示管道为单向管道;
返回值:返回两个管道流对象,分配表示管道的两端;
如果参数为True(默认),两个对象均可发送接收;
如果为False时,则第一个对象只能接收,第二个对象只能发送;
说明:1, 向管道发送数据使用send()函数,从管道接收数据使用recv() 函数;
2,recv() 函数为阻塞函数,当管道中数据为空时会阻塞;
3,一次recv() ,只能接收一次send()的内容;
4,send() 可以发送字符串数字列表等多种类型数据;
from multiprocessing import Process,Pipe
import os,time #创建管道对象
#当参数为False的时候child只能recv parent只能send
# child_conn,parent_conn = Pipe(False) child_conn,parent_conn = Pipe() #子进程函数
def fun(name):
time.sleep(1)
#发送一个字符串到管道
child_conn.send('hello' + str(name))
print(os.getppid(),"----",os.getpid()) jobs = []
#创建5个子进程
for i in range(5):
p = Process(target = fun,args = (i,))
jobs.append(p)
p.start() for i in range(5):
data = parent_conn.recv()
print(data) for i in jobs:
i.join()
消息队列:
multiprocessing ---> Queue
在内存中开辟一个队列模型,用来存放消息,任何拥有队列队形的进程都可以进行消息的存放和取出;
Queue(maxsize = 0)
功能:创建一个消息队列对象;
参数:maxsize 默认为0 表示消息队列可以存放的消息由系统自动分配的空间而定;
> 0 的正整数 表示队列中最多存放多少条消息;
返回值:消息队列对象;
q.put()
1,向消息队列中存放一条消息,当消息队列满的时候,会阻塞;
2, 存放的消息类型可以是数字,列表,字符串等;
q.full()
判断队列是否为满, 如果满则返回True,否则返回False;
q.qsize()
查看当前队列中消息数量;
q.get()
获取消息,每次获取一条; 当消息队列为空时,则为阻塞;
说明: put() 、get() 中block参数和timeout参数
block默认为True,表示两个函数都是阻塞函数;
如果设置为False, 则表示不阻塞;
timeout 当block设置为True时,表示超时等待时间;
from multiprocessing import Queue #创建消息队列对象
q = Queue(3) i = 0
# 存放消息
while True:
#判断队列是否满了
if q.full():
print("queue is full")
break
q.put("hello" + str(i))
i += 1 print("当前队列有%d条消息"%q.qsize()) for i in range(q.qsize()):
print("获取消息%s"%q.get()) print("is empty?",q.empty()) print(q.get(True,3)) print("process over")
from multiprocessing import Process,Queue
import time q = Queue() def fun(name):
time.sleep(1)
q.put("hello" + str(name)) jobs = [] for i in range(10):
p = Process(target = fun,args =(i,))
jobs.append(p)
p.start() for i in jobs:
i.join() while not q.empty():
print(q.get())
共享内存
在内存中开辟一段内存空间存储数据,每次存储的内容会覆盖上次的内容;由于没有对内存进行格式化修饰,所以存储的速度快效率高;
from multiprocessing import Value,Array
obj = Value(ctype, obj)
功能:开辟共享内存
参数:ctype 要转变的c的类型
obj 要写入共享内存的初始值
obj.value 属性为获取共享内存中的值;
from multiprocessing import Value,Process
import time
import random def deposite(money):
for i in range(100):
time.sleep(0.03)
money.value += random.randint(1,200) def withdraw(money):
for i in range(100):
time.sleep(0.02)
money.value -= random.randint(1,150) money = Value('i',2000) d = Process(target = deposite,args = (money,))
w = Process(target = withdraw,args = (money,)) d.start()
w.start() d.join()
w.join() print(money.value)
obj =Array(ctype, obj)
功能: 开辟一个共享内存空间;
参数: 要装的c的类型;
obj 放入共享内存中的数据, 是一个列表,要求列表重点数据为相同类型的数据;
如果obj传入一个正数,则表示在共享内存中开辟一个多大的空间,空间中可以存放的数值类型由ctype确定;
返回值: 返回一个可迭代对象通过for循环取值,可以进行修改;
from multiprocessing import Process,Array
import time
import ctypes def fun(shm):
for i in shm:
print(i)
# shm[0] = 'A' # shm = Array('i',[1,2,3,4,5])
shm = Array(ctypes.c_char,6) p = Process(target = fun,args = (shm,))
p.start()
p.join() for i in shm:
print(i)
############
管道 消息队列 共享内存
开辟空间 : 内存中 内存中 内存中
读写方式: 可双向/单向 先进先出,按照个数存储 操作内存
效率 : 一般 一般 较快
是否需要同步互斥 : 不需要 不需要 需要
#############
信号:
kill -l 查看系统信号
kill -signame PID 给进程号PID的进程发送signame信号;
信号: 信号名称 含义 默认处理方式
名称:系统定义
含义:系统定义
处理方式:采用默认方式处理(系统定义 终止 暂停 忽略)
忽略信号(当信号没发生过)
采用自定义方式处理
import signal
import time signal.alarm(5)
#采用默认方式
# signal.signal(signal.SIGINT,signal.SIG_DFL) #忽略该信号
signal.signal(signal.SIGINT,signal.SIG_IGN)
signal.signal(signal.SIGALRM,signal.SIG_IGN) while True:
time.sleep(2)
print("你按ctrl + c啊")
from signal import *
import os,time #信号处理函数,有固定参数格式
def handler(sig,frame):
if sig == SIGALRM:
print("收到了时钟信号")
elif sig == SIGINT:
print("收到了SIGINE就不结束") alarm(7) #通过函数 处理信号
signal(SIGALRM,handler)
signal(SIGINT,handler) while True:
print("waiting for signal")
time.sleep(2)
如何发送信号:
os.kill(pid, sig)
功能:向一个进程发送一个信号
参数:pid 指要发送进程的PID号
sig 指要发送的信号
signal.alarm(sec)
功能:给自己发送一个时钟信号(SIGALRM)
参数:esc 秒数 表示在相应的秒数后发送时钟信号
说明:1,信号是一种异步的进程间通信方式
2,alarm函数在一个进程中如果使用多次,则后面的时钟时间会覆盖前面的时间。
信号的处理:
signal.pause() 阻塞等待一个信号的发生;
signal.signal(signum, hander)
功能: 处理信号
参数:signum 表示可以处理的信号
hander 信号处理的方法:
1, 默认处理方式:SIG_DFL
2,忽略信号:SIG_IGN
3,自定义的方式: function
说明:1, signal 函数也是一个异步处理信号函数;
2, SIGSTOP 和SIKILL不能被signal函数处理;
####
僵尸进程的信号处理方案 父进程中
signal(SIGCHLD, SIG_IGN)
###
同步和互斥
临界资源:对多个进程或者线程都可见的资源,容易产生争夺,我们将这类资源叫做临界资源;
临界区:对临界资源进行操作的代码区域称之为临界区;
解决资源争夺方法: 同步 或者 互斥
同步: 同步是一种合作关系,为完成某种任务而建立的多个进程或者线程之间的协调调用,持续等待,传递消息告知资源占用情况;
互斥: 互斥是一种制约关系,当一个进程或者线程进入到临界区后会进行枷锁操作,此时其他进程或者线程无法进入到临界区,只有
当该进程或线程使用后进程解锁,其他人才可以使用,这种技术往往是通过阻塞完成;
Event 事件
Event() ----> 事件对象e
e.wait() : 产生一种阻塞 ,知道e被set之后才结束阻塞
e.set() : 将e set操作 wait不再阻塞
e.is_set() : 判断e是否是被设置的状态
e.clear() : 将e 变成 没有被设置的状态
from multiprocessing import Event #生成事件对象
e = Event() #检测事件对象,如果被设置则返回True否则返回false
print(e.is_set()) #设置事件对象
e.set() #提供事件的阻塞
e.wait() print("wait.....")
#清除对事件的设置
e.clear() e.wait() print("wait...wait.....")
from multiprocessing import Process,Event
import time def wait_event():
print('process1要等主进程操作完我才能操作')
e.wait()
print('终于操作完了,该我了',e.is_set()) def wait_event_timeout():
print('process2要等主进程操作完我才能操作')
e.wait(2)
print('我等不了了,干别的去',e.is_set()) e = Event() p1 = Process(name = 'block',\
target = wait_event)
p1.start()
p2 = Process(name = 'non-block',\
target = wait_event_timeout)
p2.start() print("假设主进程在忙碌的操作临界区")
time.sleep(3)
e.set()
print("主进程开放临界区")
练习:
1. 创建父子进程,分别表示司机和售票员
2. 当售票员捕捉到 SIGINT信号时 给司机发送SIGUSR1信号,
司机打印“老司机开车了”
当售票员捕捉到 SIGQUIT信号时 给司机发送SIGUSR2信号,
司机打印“系好安全带,小心甩出去”
当司机捕捉到 SIGTSTP信号时 给售票员发送SIGUSR1信号,
售票员打印“到站了,下车吧”
3. 到站后 售票员先下车(子进程先退出),然后司机下车
from signal import *
from multiprocessing import Process
import os
import time def saler_handler(sig,frame):
if sig == SIGINT:
os.kill(os.getppid(),SIGUSR1)
elif sig == SIGQUIT:
os.kill(os.getppid(),SIGUSR2)
elif sig == SIGUSR1:
print("python学完了,出去试试吧")
os._exit(0) def driver_handler(sig,frame):
if sig == SIGUSR1:
print("老司机带你学python")
elif sig == SIGUSR2:
print("python 知识多,积累最重要")
elif sig == SIGTSTP:
os.kill(p.pid,SIGUSR1) def saler():
signal(SIGINT,saler_handler)
signal(SIGQUIT,saler_handler)
signal(SIGUSR1,saler_handler)
signal(SIGTSTP,SIG_IGN)
while True:
time.sleep(2)
print("开着python去远方") p = Process(name = 'zhangjie',\
target = saler)
p.start() # 父进程处理信号部分
signal(SIGUSR1,driver_handler)
signal(SIGUSR2,driver_handler)
signal(SIGTSTP,driver_handler)
signal(SIGINT,SIG_IGN)
signal(SIGQUIT,SIG_IGN) p.join()
Python之路PythonThread,第三篇,进程3的更多相关文章
- Python之路(第四十篇)进程池
一.进程池 进程池也是通过事先划分一块系统资源区域,这组资源区域在服务器启动时就已经创建和初始化,用户如果想创建新的进程,可以直接取得资源,从而避免了动态分配资源(这是很耗时的). 线程池内子进程的数 ...
- Python之路PythonThread,第二篇,进程2
python3 进程2 僵尸进程处理方法: 3,创建二级子进程处理 4,在父进程中使用信号处理的方法忽略子进程发来的信号: signal(SIGCHLD,DIG,IGN) # 创建二级子进场解决僵 ...
- Python之路PythonThread,第一篇,进程1
python3 进程1 多任务编程: 可以有效的利用计算机资源,同时执行多个任务, 进程:进程就是程序在计算机中一次执行的结果: 进程和程序的区别: 程序是一个静态文件的描述,不占用计算机的系统资源: ...
- Python之路【第三篇补充】:Python基础(三)
参考老师:http://www.cnblogs.com/wupeiqi lambda表达式 学习条件运算时,对于简单的 if else 语句,可以使用三元运算来表示,即: # 普通条件语句 if 1 ...
- Python之路【第三篇】:Python基础(二)
函数的理解 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 函数作用是你的程序有良好的扩展性.复用性. 同样的功能要是用3次以上的话就建议 ...
- 【Python之路】第三篇--Python基本数据类型
运算符 1.算数运算: # 在py2的 取整除运算中 9//2 = 4.0 # 引入 from __future__ import division 9//2 = 4.5 # py3中不需要! 2.比 ...
- Python之路【第三篇】:文件操作
一.文件操作步骤 打开文件,得到文件句柄并赋值给一个变量 通过句柄对文件进行操作 关闭文件 歌名:<大火> 演唱:李佳薇 作词:姚若龙 作曲:马奕强 歌词: 有座巨大的停了的时钟 倾倒在赶 ...
- Python之路【第三篇】python基础 之基本数据类型 补充
字符串格式化 Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-310 ...
- Python之路【第三篇】:模块
定义: 包:包含__init__.py文件.模块(也是.py文件) 当包被其它模块调用时,首先会执行该包下的__init__文件 包含有模块,包可以有多级 模块的导入: import from...i ...
- Python之路【第三篇】编码
Python代码——>字节码——>机器码——>计算机 Windows: cmd ==> python 文件路径 cmd ==>python >> 输入命令 L ...
随机推荐
- Javascript 将 HTML 页面生成 PDF 并下载
最近碰到个需求,需要把当前页面生成 pdf,并下载.弄了几天,自己整理整理,记录下来,我觉得应该会有人需要 :) html2canvas 简介 我们可以直接在浏览器端使用html2canvas,对整个 ...
- Vue 项目骨架屏注入与实践
作为与用户联系最为密切的前端开发者,用户体验是最值得关注的问题.关于页面loading状态的展示,主流的主要有loading图和进度条两种.除此之外,越来越多的APP采用了“骨架屏”的方式去展示未加载 ...
- 3.Liunx网络管理命令
大纲: 1.网络信息:hostname.netstat.ifconfig ,route 2.网络配置:netconfig 3.网络测试:ping
- Windows下定时任务
windows计划任务 1.写一个PHP程序,命名为test.php,内容如下所示: <? $fp = fopen("test.txt", "a+"); ...
- nginx升级教程
1.说明 CVE-2016-4450,可通过构造特定数据包,可引发nginx引用空指针,导致nginx出错从而造成拒绝服务攻击. 影响1.3.9到1.11.0的所有版本,进行修复的1.10.1和1.1 ...
- Kali配置教程
1.配置软件源 所有操作没有说明,都是以root身份执行. 打开一个终端执行: cat >> /etc/apt/sources.list <<EOF deb http://mi ...
- Spring FactoryBean应用
Spring 中有两种类型的Bean,一种是普通Bean,另一种是工厂Bean 即 FactoryBean.FactoryBean跟普通Bean不同,其返回的对象不是指定类的一个实例,而是该Facto ...
- OGG文件获取创建日期
转载:http://blog.sina.com.cn/s/blog_b0ed98070102v1tr.html 搜索关键字: OGG文件的数据结构以及读取其注释信息的代码 实例说明: "DA ...
- Java 求两个数百分比%
int num1 = 500; int num2 = 312; // 创建一个数值格式化对象 NumberFormat numberFormat = NumberFormat.getInstance( ...
- react router @4 和 vue路由 详解(四)vue如何在路由里面定义一个子路由
完整版:https://www.cnblogs.com/yangyangxxb/p/10066650.html 6.vue如何在路由里面定义一个子路由? 给父路由加一个 children:[] 参考我 ...