python中的thread_python中的线程(Thread)

  • Post author:
  • Post category:python


python中的多线程是伪多线程。多线程是在一个进程里面的,多线程不能并行进行,只能并发进行。多线程是数据共享的。

并行:一般针对进程,多个CPU同时处理多个进程。并行中没有GIL锁

并发:一般针对线程,一个CPU在多个线程之间来回切换。并发中有GIL锁

80420be91dbf179170becc64ac5e1809.png

多线程处理数据流程:一个进程里面的有多个线程,python解释器里面有一把GIL锁, 到达python解释器的多线程们会和GIL锁见面,但是GIL锁每次只允许一个线程进入CPU,该线程通过GIL锁进入CPU的时候,GIL会锁上门,禁止其他线程进入,所有其他线程必须在锁外边等待进入CPU的那个线程出来以后才能进去,进去的线程会随机选择一个cpu, 固定时间后被赶出去,如果任务还没全部完成,保留资源点,回到锁外跟外面的多线程继续竞争,每次竞争都只有一个线程能进去cpu处理数据,直到所有的线程都完成任务。

from threading import Thread

num = 0

def run1():

global num

for i in range(10000):

num += 1

def run2():

global num

for i in range(10000):

num += 1

if __name__ == ‘__main__’:

t1 = Thread(target=run1)

t2 = Thread(target=run2)

t1.start()

t2.start()

t1.join()

t2.join()

print(num)

>> 20000

join()阻塞:表示必须等子线程执行完之后再取执行后面的代码

多线程的执行方式:每次只能拿一个CPU处理线程,一个CPU会在多 个线程之间进行切换,CPU的执行方式有可能是按片段执行,相当于没执行完就退出,去执行另一个线程,所以全局变量在多线程之间就会发生数据混乱。

解决方案:

​加锁lock.acquire(), 解锁lock.release(), 加锁来解决数据错乱问题。加锁可以让数据全部执行完。

from threading import Thread, Lock

lock = Lock()

num = 0

def run1():

global num

for i in range(100000):

# 加锁

lock.acquire()

num += 1

# 解锁

lock.release()

def run2():

global num

for i in range(100000):

lock.acquire()# 加锁

num += 1

lock.release()# 解锁

if __name__ == ‘__main__’:

t1 = Thread(target=run1)

t2 = Thread(target=run2)

t1.start()

t2.start()

t1.join()

t2.join()

print(num)

>> 200000

多线程中局部变量不共享

线程隔离:把每一个线程id当做字典的key值,value值是请求方法,每次去取值去取线程id.

进程和线程的数据不是越多越好,创建进程和线程数量的标准,最多是电脑配置核数的两倍。



版权声明:本文为weixin_33206646原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。