进程是CPU资源分配和调度的独立单位
线程是CPU最小的执行单元
协程是程序根据自己的需求来进行调度的
一、进程
(1)编写多进程一般使用跨平台版本的模块 multiprocessing
,它提供了对进程的一系列操作
from multiprocessing import Process
//进程要执行的代码
def say(name):
print("%s say hello"%name)
if __name__="__main__":
p = Process(target=say,args=("laowang",)
p.start
p.join
p.close
(2)如果需要多个进程,就可以使用进程池Pool
(3)进程间的通讯,因为不是同一个上下文环境,需要先对数据进行pickle序列化,然后可以使用Queue、Pipes
进行数据的传递
# 在父进程中创建两个子进程
# 初始化通信队列
# 定义两个函数,一个从队列里消费数据,一个生产数据。也就是一个简单的生产者消费者模型了
from multiprocessing import Process, Queue
def write(q):
for value in ["a","b","c"]:
q.put(value)
def read(q):
while True:
value = q.get()
if __name__ ="__main__":
q = Queue()
pw = Process(target=write,args=(q,))
pr = Process(target=read,args=(q,))
pw.start()
pr.start()
pw.join()
pr.terminate()
(4)由于多进程通信部不是很方便,多任务也可以使用多进程完成任务 也可以使用多线程完成任务
(5) 进程 是由若干线程组成的,一个进程至少有一个线程
二、线程
(1)python的标准库提供了两个多线程模块:_threading、threading
-
_threading
是普通库,threading
是高级模块,对_threading
进行了封装
import threading
def look():
for i in range(100):
print(i)
if __name__="__main__":
t = threading.Thread(target=look,name='look_this') #如果函数有参数,也是使用args接收一个元祖, 自定义进程的名字,可以不设置,默认thread1、thread2.....
t.start()
t.join()
(2)多线程和多进程最大的不同在于
-
多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响.
-
而多线程中,所有变量都由所有线程共享,所以,任何一个变量都可以被任何一个线程修改
-
因此,线程之间共享数据最大的危险在于多个线程同时改一个变量,把内容给改乱了
-
这时候就需要一把锁了,用来锁住当前执行的线程。
-
创建一个锁 可以使用
threading.Lock
来完成
lock = threading.Lock()
def run_thread(n):
for i in range(100000):
# 先要获取锁:
lock.acquire()
try:
# 放心地改吧:
print(n)
finally:
# 改完了一定要释放锁:
lock.release()
-
Python的线程虽然是真正的线程,但解释器执行代码时,有一个GIL锁:Global Interpreter Lock,任何Python线程执行前,必须先获得GIL锁
-
然后,每执行100条字节码,解释器就自动释放GIL锁,让别的线程有机会执行。这个GIL全局锁实际上把所有线程的执行代码都给上了锁。
-
多线程在Python中只能交替执行,即使100个线程跑在100核CPU上,也只能用到1个核
-
Python虽然不能利用多线程实现多核任务,但可以通过多进程实现多核任务,当然也可以使用协程来完成
-
多个Python进程有各自独立的GIL锁,互不影响。
-
Python解释器由于设计时有GIL全局锁,导致了多线程无法利用多核。多线程的并发在Python中就是一个美丽的梦。
网友评论