进程:进程是操作系统资源分配的基本单位。
线程:线程是任务调度和执行的基本单位。
一个应用程序至少一个进程,一个进程至少一个线程。
两者区别:同一进程内的线程共享本进程的资源如内存、I/O、cpu等,但是进程之间的资源是独立的。
多进程
from multiprocessing import Process
def run_proc(name):
print('Run child process %s (%s)...'% (name, os.getpid()))
if __name__ =='__main__':
print('Parent process %s.'% os.getpid())
p = Process(target=run_proc, args=('test',))
print('Child process will start.')
p.start()
p.join()
print('Child process end.')
如果要启动大量的子进程,可以用进程池pool的方式批量创建子进程:
from multiprocessing import pool
if __name__=='__main__':
print('Parent process %s.'% os.getpid())
p = Pool(4)
for i in range(5):
p.apply_async(long_time_task, arg=(i,))
print('Waiting for all subprocesses done...')
p.close()
p.join()
print('All subprocesses done.')
对Pool对象调用join()方法会等待所有子进程执行完毕,调用join()之前必须先调用close(),调用close()之后就不能继续添加新的Process了
子进程
subprocess模块可以让我们非常方便地启动一个子进程,然后控制其输入和输出。
import subprocess
r = subprocess.call(['nslookup','www.python.org'])
如果子进程还需要输入,则可以通过communicate()方法输入:
import subprocess
print('$ nslookup')
p = subprocess.Popen(['nslookup'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, err = p.communication(b'set q=mx\npython.org\nexit\n')
print(output.decode('utf-8'))
print('Exit code:', p.returncode)
在输入nslookup后,手动输入:
set q=mx
python.org
exit
进程间通信方式:Queue, Pipes
多线程
import threading
t = treading.Thread(target=loop, name='LoopThread')
t.start()
t.join()
Python的线程虽然是真正的线程,但解释器执行代码时,有一个GIL锁:Global Interpreter Lock,任何Python线程执行前,必须先获得GIL锁,然后,每执行100条字节码,解释器就自动释放GIL锁,让别的线程有机会执行, GIL全局锁实际上把所有线程的执行代码都给上了锁,所以,多线程在Python中只能交替执行
进程间通信的几种方式:队列,管道,进程池,manager类
线程间通信的几种方式:加锁,队列
计算密集型 vs. IO密集型
计算密集型任务的特点是要进行大量的计算,消耗CPU资源
计算密集型任务由于主要消耗CPU资源,因此,代码运行效率至关重要。Python这样的脚本语言运行效率很低
IO密集型,涉及到网络、磁盘IO的任务都是IO密集型任务,CPU消耗很少,任务的大部分时间都在等待IO操作完成,常见的大部分任务都是IO密集型任务,比如Web应用
网友评论