阅读 97

【Python】多线程的实现及其存在的问题

Python 多线程

python主要是通过thread和threading这两个模块来实现多线程支持。python的thread模块是比较底层的模块,python的threading模块是对thread做了一些封装,可以更加方便的被使用。

创建新的线程有两种方法:

  1. 通过 threading.Thread() 传递给 Thread 对象一个可执行方法(或对象)

  2. 继承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虚拟机按照以下方式执行:

  1. 设置GIL

  2. 切换到一个线程并执行

  3. 线程执行完成或设置为睡眠状态(最多执行100条字节码)

  4. 解锁GIL

  5. 重复 1-4

不管有几个核,单位时间多个核只能跑一个线程,然后时间片轮转。

如果需要充分利用多核,可使用 multiprocessing 库,创建多进程。


作者:Hazelnut
链接:https://juejin.cn/post/7056355890407931941


文章分类
百科问答
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐