python通过多进程实行多任务
#原创,转载请联系
在开始之前,我们要知道什么是进程。道理很简单,你平时电脑打开QQ客户端,就是一个进程。再打开一个QQ客户端,又是一个进程。那么,在python中如何用一篇代码就可以开启几个进程呢?通过一个简单的例子来演示:
import multiprocessing
import time def task1():
while True:
time.sleep(1)
print("I am task1") def task2():
while True:
time.sleep(2)
print("I am task2") if __name__ == '__main__':
p1 = multiprocessing.Process(target=task1) # multiprocessing.Process创建了子进程对象p1
p2 = multiprocessing.Process(target=task2) # multiprocessing.Process创建了子进程对象p2
p1.start() # 子进程p1启动
p2.start() # 子进程p2启动
print("I am main task") # 这是主进程的任务 输出结果:
I am main task
I am task1
I am task2
I am task1
I am task1
I am task2
I am task1
I am task1
I am task2
...
...
可以看到子进程对象是由multiprocessing模块中的Process类创建的。除了p1,p2两个被创建的子进程外。当然还有主进程。主进程就是我们从头到尾的代码,包括子进程也是由主进程创建的。
注意的点有:
1.首先解释一下并发:并发就是当任务数大于cpu核数时,通过操作系统的各种任务调度算法,实现多个任务“一起”执行。(实际上总有一些任务不在执行,因为切换任务相当快,看上去想同时执行而已。)
2.当是并发的情况下,子进程与主进程的运行都是没有顺序的,CPU会采用时间片轮寻的方式,哪个程序先要运行就先运行哪个。
3.主进程会默认等待所有子进程执行完毕后,它才会退出。所以在上面的例子中,p1,p2子进程是死循环进程,主进程的最后一句代码print("I am main task")虽然运行完了,但是主进程并不会关闭,他会一直等待着子进程。
4.主进程默认创建的是非守护进程。注意,结合3.和5.看。
5.但是!但是!如果子进程是守护进程的话,那么主进程运行完最后一句代码后,主进程会直接关闭,不管你子进程运行完了没有!
-------------------------------------------------------------------------------------------------------------我是一条分割线------------------------------------------------------------------------------------------------------------------------------------
不相信?
那我们来测试下
import multiprocessing
import time def task1():
while True:
time.sleep(1)
print("I am task1") def task2():
while True:
time.sleep(2)
print("I am task2") if __name__ == '__main__':
p1 = multiprocessing.Process(target=task1)
p2 = multiprocessing.Process(target=task2)
p1.daemon = True # 设置p1子进程为守护进程
p2.daemon = True # 设置p2子进程为守护进程
p1.start()
p2.start()
print("I am main task") 输出结果:
I am main task
输出结果是不是有点奇怪。为什么p1,p2子进程都没有输出的?
让我们来整理一下思路:
1.创建p1,p2子进程
2.设置p1,p2子进程为守护进程
3.p1,p2子进程开启
4.p1,p2子进程代码里面都有休眠时间,所以cpu为了不浪费时间,先做主进程后续的代码。
5.执行主进程后续的代码,print("I am main task")
6.主进程后续的代码执行完成了,所以剩下的子进程是守护进程的,全都要关闭了。但是,如果主进程的代码执行完了,有两个子进程,一个是守护的,一个非守护的,怎么办呢?其实,他会等待非守护的那个子进程运行完,然后三个进程一起关闭。
7.p1,p2还在休眠时间内就被终结生命了,所以什么输出都没有。
里面涉及到两个知识点:
1.当主进程结束后,会发一个消息给子进程(守护进程),守护进程收到消息,则立即结束
2.CPU是按照时间片轮寻的方式来运行多进程的。哪个合适的哪个运行,如果你的子进程里都有time.sleep。那我CPU为了不浪费资源,肯定先去干点其他的事情啊。
那么,守护进程随时会被中断,他的存在意义在哪里的?
其实,守护进程主要用来做与业务无关的任务,无关紧要的任务,可有可无的任务,比如内存垃圾回收,某些方法的执行时间的计时等。
-------------------------------------------------------------------------------------------------------------我是一条分割线------------------------------------------------------------------------------------------------------------------------------------
虽然知道怎么简单的创建子进程,但是如果要创建的子进程要传入参数,应该怎么操作呢?
import multiprocessing def task(a,b,*args,**kwargs):
print("a")
print("b")
print(args)
print(kwargs) if __name__ == '__main__':
p1 = multiprocessing.Process(target=task,args=(1,2,3,4,5,6),kwargs={"name":"chichung","age":23})
p1.start()
print("主进程已经运行完最后一行代码啦") 输出: 主进程已经运行完最后一行代码啦
a
b
(3, 4, 5, 6)
{'name': 'chichung', 'age': 23}
子进程要运行的函数需要传入变量a,b,一个元组,一个字典。我们创建子进程的时候,变量a,b要放进元组里面,task函数取的时候会把前两个取出来,分别赋值给a,b了。
-------------------------------------------------------------------------------------------------------------我是一条分割线------------------------------------------------------------------------------------------------------------------------------------
创建的子进程有几个常用的方法:
p.start | 开始执行子线程 |
p.name | 查看子进程的名称 |
p.pid | 查看子进程的id |
p.is_alive | 判断子进程是否存活 |
p.join(timeout) |
阻塞主进程,当子进程p运行完毕后,再解开阻塞,让主进程运行后续的代码 如果timeout=2,就是阻塞主进程2s,这2s内主进程不能运行后续的代码。过了2s后,就算子进程没有运行完毕,主进程也能运行后续的代码 |
p.terminate | 终止子进程p的运行 |
import multiprocessing def task(a,b,*args,**kwargs):
print("a")
print("b")
print(args)
print(kwargs) if __name__ == '__main__':
p1 = multiprocessing.Process(target=task,args=(1,2,3,4,5,6),kwargs={"name":"chichung","age":23})
p1.start()
print("p1子进程的名字:%s" % p1.name)
print("p1子进程的id:%d" % p1.pid)
p1.join()
print(p1.is_alive()) 输出:
p1子进程的名字:Process-1
p1子进程的id:19345
a
b
(3, 4, 5, 6)
{'name': 'chichung', 'age': 23}
False
这个没什么好说的,自己体会一下......
-------------------------------------------------------------------------------------------------------------我是一条分割线------------------------------------------------------------------------------------------------------------------------------------
进程之间是不可以共享全局变量的,即使子进程与主进程。道理很简单,一个新的进程,其实就是占用一个新的内存空间,不同的内存空间,里面的变量肯定不能够共享的。实验证明如下:
import multiprocessing g_list = [123] def task1():
g_list.append("task1")
print(g_list) def task2():
g_list.append("task2")
print(g_list) def main_process():
g_list.append("main_processs")
print(g_list) if __name__ == '__main__':
p1 = multiprocessing.Process(target=task1)
p2 = multiprocessing.Process(target=task2)
p1.start()
p2.start()
main_process() 输出:
[123, 'main_processs']
[123, 'task1']
[123, 'task2']
一针见血了吧,哈哈~
----------------------------------------------------------------------------------------------------------我是一条结束线,谢谢观看~-----------------------------------------------------------------------------------------------------------------------
python通过多进程实行多任务的更多相关文章
- python中多进程+协程的使用以及为什么要用它
前面讲了为什么python里推荐用多进程而不是多线程,但是多进程也有其自己的限制:相比线程更加笨重.切换耗时更长,并且在python的多进程下,进程数量不推荐超过CPU核心数(一个进程只有一个GIL, ...
- 【python】多进程锁multiprocess.Lock
[python]多进程锁multiprocess.Lock 2013-09-13 13:48 11613人阅读 评论(2) 收藏 举报 分类: Python(38) 同步的方法基本与多线程相同. ...
- Python实现多进程
Python可以实现多线程,但是因为Global Interpreter Lock (GIL),Python的多线程只能使用一个CPU内核,即一个时间只有一个线程在运行,多线程只是不同线程之间的切换, ...
- 『Python』多进程处理
尝试学习python的多进程模组,对比多线程,大概的区别在: 1.多进程的处理速度更快 2.多进程的各个子进程之间交换数据很不方便 多进程调用方式 进程基本使用multicore() 进程池优化进程的 ...
- python 使用多进程实现并发编程/使用queue进行进程间数据交换
import time import os import multiprocessing from multiprocessing import Queue, pool ""&qu ...
- Python多线程多进程
一.线程&进程 对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程, ...
- Python的多进程
这里不说其它,Python的多进程网上已经有很多了,可以尽情搜索.但是用多进程一般是采用对任务的方式,所以注意文件锁定.一般采用Pool是比较合适的.给个网友的小代码 from multiproces ...
- 进程,线程,以及Python的多进程实例
什么是进程,什么是线程? 进程与线程是包含关系,进程包含了线程. 进程是系统资源分配的最小单元,线程是系统任务执行的最小单元. 打个比方,打开word,word这个程序是一个进程,里面的拼写检查,字数 ...
- 进程与线程(2)- python实现多进程
python 实现多进程 参考链接: https://morvanzhou.github.io/tutorials/python-basic/multiprocessing/ python中实现多进程 ...
随机推荐
- AtomicIntegerFieldUpdater使用
假设现在有这样的一个场景: 一百个线程同时对一个int对象进行修改,要求只能有一个线程可以修改. 看看下面程序是否正确: private static int a = 100; private sta ...
- 【python】实现一个python编程的小时钟!
[本实验内容] 1.GUI.PyQT5介绍2.实现此次实验效果 [一 GUI.PyQt5介绍] 1.Python简介 2.GUI介绍 几个常用的Python GUI库: (1)wxPython (2) ...
- perf 对两个map是否重叠的判断,以及函数map_groups__fixup_overlappings代码逻辑
该标题可以抽象出来的问题是:两个前开后闭的区间 rangeA 和 rangeB,如何判断这两个区间是否重叠.这个问题在内核中非常重要,虚拟地址空间的划分需要它,perf中map_group的构建也需要 ...
- 日期时间选择器datetimepicker.js
在做项目中,往往会遇到需要用户输入2014-07-19 09:55:53这样的格式的数据.就是典型的年月日时分秒这样的格式.这个时候,使用datetimepicker会比较简单. DateTimePi ...
- BZOJ4415 SHOI2013发牌(线段树)
似乎是noip2017d2t3的一个部分分.用splay的话当然非常裸,但说不定会被卡常.可以发现序列中数的(环上)相对位置是不变的,考虑造一棵权值线段树维护权值区间内还有多少个数留在序列中,每次在线 ...
- 计蒜客16492 building(二分线段树/分块)
题解: 考虑用线段树维护楼的最大值,然后这个问题就很简单了. 每次可以向左二分出比x高的第一个楼a,同理也可以向右二分出另一个楼b,如果a,b都存在,答案就是b-a-1. 注意到二分是可以直接在线段树 ...
- [CF15C]Industrial Nim
题目大意:有$n$个采石场,每行一个$m_i$一个$x_i$,表示第$i$个采石场有$m_i$辆车,这个采石场中车中的石子为从$x_i$开始的自然数.Nim游戏若先手赢输出"tolik&qu ...
- [洛谷P3195][HNOI2008]玩具装箱TOY
题目大意:有n个物体,大小为$c_i$.把第i个到第j个放到一起,容器的长度为$x=j-i+\sum\limits_{k-i}^{j} c_k$,若长度为x,费用为$(x-L)^2$.费用最小. 题解 ...
- [洛谷P2384]最短路
题目大意:给你一个图,要你求出其中1->n路径中乘积最小的一条路 题解:用$log_2$把乘法变成加法,然后记录每个点的前驱,最后求出答案 C++ Code: #include<cstdi ...
- HAOI2006 均分数据 [模拟退火]
题目描述 已知N个正整数:A1.A2.--.An .今要将它们分成M组,使得各组数据的数值和最平均,即各组的均方差最小.均方差公式如下: 输入输出格式 输入格式: 输入文件data.in包括: 第一行 ...