【Python】多线程的实现及其存在的问题
Python 多线程
python主要是通过thread和threading这两个模块来实现多线程支持。python的thread模块是比较底层的模块,python的threading模块是对thread做了一些封装,可以更加方便的被使用。
创建新的线程有两种方法:
通过
threading.Thread()
传递给Thread
对象一个可执行方法(或对象)继承
threading.Thread
定义子类并重写run()
方法
threading.Thread()
主要参数:
target
:Callable,可执行方法name
:str,线程名args
:Iterable[Any],可执行方法的参数列表daemon
:bool,这个线程是否是守护线程
示例代码
import random import threading from time import sleep def myPrint(odd: bool): """odd 为 True 输出奇数,否则输出偶数""" for i in range(10): if odd and i % 2 == 1: print(i) elif not odd and i % 2 == 0: print(i) sleep(random.random()) t1 = threading.Thread(target= myPrint, args=(True, )) t2 = threading.Thread(target= myPrint, args=(False, )) t1.start() t2.start() 复制代码
运行代码,奇数和偶数混合输出,而不是先输出全部奇数,再输出全部偶数。
继承threading.Thread
通过继承 threading.Thread
定义子类创建多线程,直接从 threading.Thread
继承,然后重写 init
方法和 run
方法。因为继承了 threading.Thread
,调用 start
方法时,会自动运行其 run
方法中的代码。
示例代码:
class myCPrint(threading.Thread): def __init__(self , odd): super(myCPrint,self).__init__() self.odd = odd def run(self): for i in range(10): if self.odd and i % 2 == 1: print(i) elif not self.odd and i % 2 == 0: print(i) sleep(random.random()) c1 = myCPrint(True) c2 = myCPrint(False) c1.start() c2.start() 复制代码
运行代码,同样可以看到奇数和偶数混合输出,而不是先输出全部奇数,再输出全部偶数。
Python 多线程存在的问题
Python中的多线程是假的多线程
Python 代码的执行由 Python 虚拟机(解释器)来控制。Python在设计之初就考虑要在主循环中,同时只有一个线程在执行。对 Python 虚拟机的访问由全局解释器锁(GIL)来控制,正是这个锁保证同时只有一个线程在运行。在多线程环境中,Python虚拟机按照以下方式执行:
设置GIL
切换到一个线程并执行
线程执行完成或设置为睡眠状态(最多执行100条字节码)
解锁GIL
重复 1-4
不管有几个核,单位时间多个核只能跑一个线程,然后时间片轮转。
如果需要充分利用多核,可使用 multiprocessing
库,创建多进程。
作者:Hazelnut
链接:https://juejin.cn/post/7056355890407931941