Python多进程和多线程
2019-11-13 本文已影响0人
陈忠俊
Python是跨平台的动态语言,自然是支持多线程和多进程的。其多进程是模仿多线程开发出来的。
进程,是一个程序在某个数据集合上的运行活动。比如,你用QQ音影打开了一部电影,这个时候就启动了一个进程。
线程,是程序的最小执行单元,线程属于进程。一个进程可以启动多个线程,反之不成立。
查看当前CPU的核心数:
>>> from os import cpu_count
>>> cpu_count()
8
上面给的是逻辑核心,现在好一点的处理器都是支持超线程技术,物理核心是4个。
尝试启动一个进程:
from multiprocessing import Process
import time
def func(args):
for i in args:
print(i)
time.sleep(1)
if __name__ == '__main__':
p = Process(target = func, args = ([1,3,5,7,9],)) #创建一个进程
p.start() #启动子进程
p.join() #等待子进程结束
print("Done")
也可以通过进程池的方式一次启动多个进程:
from multiprocessing import Pool
import time
import random
import os
def func(id):
print("run task: ", id)
time.sleep(random.random() * 10)
print("task done: ", id)
if __name__ == '__main__':
thread_num = os.cpu_count() # 获取cpu逻辑核心数
p = Pool(thread_num) # 创建进程池
for i in range(thread_num + 1): # 创建比CPU逻辑核心数+1个进程,可以看到一个进程在等待
p.apply_async(func, args = (i,))
p.close()
p.join()
print("Done")
输出结果:
run task: 0
run task: 1
run task: 2
...
run task: 6
run task: 7
task done: 2
run task: 8 # 该进程 在进程-2运行完成之后再启动
task done: 1
创建进程池p = Pool()
,这里p
有apply
,apply_async
两个方法,其一是同步,第二个是异步。
同步,可以理解为单行道汽车过红绿灯,前面的车没过去,后面的车只能等待。
异步,可以理解为多车道的车过绿灯,每辆车在绿灯的情况下,按自己的情况开走,不用等待其他车道的车。
Python多进程会利用多核的优势,但是在多任务调度过程中,又会消耗大量的cpu资源。这个要看具体的任务。
由于GIL的存在,Python在多线程情景中,对于IO的任务,多线程会加快运行速度,而对于计算密集型的任务,多线程将不适合。
from threading import Thread
import random
import time
class MyThread(Thread):
def __init__(self, threadId, **kwargs):
super().__init__()
self.threadId = threadId
self.dic = kwargs
self.start() # 创建新的线程时就启动该线程
def run(self):
print("Start thread: ", self.threadId)
test(self.dic)
time.sleep(random.random() * 5)
print("Thread: %s done" %self.threadId)
def test(kwargs):
for i in kwargs:
print("%s: %s" %(i, kwargs[i]))
if __name__ == "__main__":
threads = []
for i in range(3):
threads.append(MyThread(i, name = 'eclipse', age = 30))
for th in threads:
th.join() #等待所以线程结束
输出:
Start thread: 0
name: eclipse
age: 30
Start thread: 2
name: eclipse
Start thread: 1
age: 30
name: eclipse
age: 30
Thread: 0 done
Thread: 1 done
Thread: 2 done
All threads done!