进程
进程是一个执行中的程序。每个进程都拥有自己的地址空间、内存、数据栈以及其他用于跟踪执行的辅助数据。在单核CPU系统中的多进程,内存中可以有许多程序,但在给定一个时刻只有一个程序在运行;就是说,可能这一秒在运行进程A,下一秒在运行进程B,虽然两者都在内存中,都没有真正同时运行。
进程是系统资源分配的最小单位;进程有自己独立的内存空间(数据不共享,开销大)
一. 利用Process实现多进程
from multiprocessing import Process, Pool
def do_work():
print('进程正在执行, 进程ID: {}'.format(Process.pid))
if __name__ == '__main__':
p = Process(target=do_work)
p2 = Process(target=do_work)
p.start()
p2.start()
p.join()
p2.join()
二. 利用进程池实现多进程
from multiprocessing import Process, Pool
def do_work():
print('进程正在执行, 进程ID: {}'.format(Process.pid))
if __name__ == '__main__':
pool = Pool(processes=2)
for i in range(0, 2):
pool.apply_async(do_work)
pool.close()
pool.join()
三. python3.2以后进程池的标准库 ProcessPoolExecutor
from concurrent.futures import ProcessPoolExecutor
from time import sleep
def loop(nloop, nsec):
print("start process", nloop)
sleep(nsec)
print("end process", nloop)
if __name__=="__main__":
with ProcessPoolExecutor(max_workers=3) as executor:
all_task = [executor.submit(loop, i, j) for i, j in zip([1, 2], [4, 3])]
线程
线程是调度执行的最小单位,从属于进程,是程序的实际执行者。一个进程至少包含一个主线程,也可以有更多的子线程。Python可以运行多线程,但和单核CPU多进程一样,在给定时刻只有一个线程会执行。
多个线程共享内存(数据共享,共享全局变量),提高程序运行效率
一. 利用threading创建多线程
from threading import Thread
from time import sleep
def do_work(params):
print('start Thread {}'.format(params))
sleep(5)
print('end Thread {}'.format(params))
if __name__ == '__main__':
th = Thread(target=do_work, args=('th', ))
th2 = Thread(target=do_work, args=('th2', ))
th.start()
th2.start()
th.join()
th2.join()
二. 利用线程池创建多线程
from concurrent.futures import ThreadPoolExecutor
def do_work(params):
print('start Thread {}'.format(params))
sleep(5)
print('end Thread {}'.format(params))
if __name__ == '__main__':
with ThreadPoolExecutor(max_workers=3) as executor:
all_task = [executor.submit(do_work, i) for i in range(1, 3)]
协程
协程:一种用户态的轻量级线程,协成的调度完全由用户控制;是一种比线程更加轻量级的存在。正如一个进程可以拥有多个线程一样,一个线程也可以拥有多个协程。最重要的是,协程不是被操作系统内核所管理,而完全是由程序所控制
协程拥有自己的寄存器,上下文和栈;
协程调度切换时,将寄存器上下文和栈保存到其他地方;
切回来的时候,回复先前保存的寄存器上下文和栈;
直接操作栈基本没有内核操作的开销,不加锁访问全局变量,上下文切换很快;
一.gevent 实现协程
import gevent
def eat(name):
print('%s eat 1' %name)
gevent.sleep(2)
print('%s eat 2' %name)
def play(name):
print('%s play 1' %name)
gevent.sleep(1)
print('%s play 2' %name)
if __name__ == '__main__':
g1 = gevent.spawn(eat, 'egon')
g2 = gevent.spawn(play, name='egon')
g1.join()
g2.join()