python 多线程

简介:

真正的多线程吗?

对于多核处理器,在同一时间确实可以多个线程独立运行,但在Python中确不是这样的了。原因在于,python虚拟机中引入了GIL这一概念。GIL(Global Interpreter Lock)全局解析器锁是用来解决共享资源访问的互斥问题,导致在python虚拟机中同一时间只能有一个线程访问python所提供的API。

那么python是如何支持多线程的呢?

在操作系统中系统通过时钟中断进行进程的调度,而python正是参考这个原理。在python内部维护了一个内部的时钟,来记录每个线程每个时钟周期执行命令的数量。

>>> import sys
>>> sys.getcheckinterval() #获取一个始终周期内执行指令数
100

当一个线程获得了python虚拟机的GIL后可以按顺序执行100条指令,然后挂起当前进程,切换下一个等待执行的线程。

那么python如何选择下一个需要执行的线程呢?

python并没有去实现一个线程优先级调度算法,而是将线程选择问题交给了底层的操作系统,也就是说python借用了底层操作系统所提供的线程调度机制来决定下一个执行的线程。

因此,python使用的就是操作系统原生的线程,只是python在其基础之上提供了一套统一的抽象机制。

线程切换

在操作系统中,进程之间的切换需要不断保存和恢复进程之间的上下文环境,保证每一个进行都能在其对应的上下文环境中运行。python正是参考操作系统的切换机制,为每一个线程创建一个保存线程状态信息的PyFrameObject对象。在python中有有一个全局变量PyThreadState *_PyThreadState_Current用来保存当前活动线程的线程状态对象。

下一线程切换需要的线程状态如何获取?

在python中通过一个单项链表来管理所有的python线程对象(保护线程的状态信息和线程信息,例如线程id),当需要寻找一个线程对应的状态对象时,就遍历这个链表,搜索其对应的状态对象。

这个状态对象链表并不会受到GIL的保护,而是有其专用的锁。

需要注意

当前活动的python线程不一定是获得了GIL的线程,例如“主线程获得了GIL,子线程还没有申请到GIL时也没有挂起,而且主线程和子线程都是操作系统原生的线程,操作系统可能在主线程和子线程之间进行切换(操作系统的线程切换是不受python虚拟机控制的,属于操作系统自身行为)”。python虚拟机的调度是一定是获得GIL基础之上的,而操作系统级的就不一定获得GIL了。

虽有操作系统会把未获得GIL的线程切换为活动线程,但是该线程发现自身并没有获得GIL会自动挂起。

只有当所有线程都完成了初始化操作,操作系统的线程调度和Python线程调度才会一致。那时,python的线程调度会迫使当前活动线程释放GIL,导致触发GIL中维护的Event内核对象,从而触发操作系统的线程调度。(在初始化完成之前,python线程调度和操作系统调度之间没有因果关系)

阻塞调度和线程销毁

在python中如果有raw_input等待输入的操作时将自身阻塞后,并将等待GIL线程唤醒,这种情况成为阻塞调度。

在线程通过阻塞调度切换时,python内部的时钟周期技术_Py_Ticker依然会被保持,不会被重置。

python的主线程销毁和子线程销毁是不同的,子线程只需要维护引用计数,而主线程还需要销毁运行环境。

用户级互斥和同步

上面讨论的GIL属于python内合计互斥,实现了保护内存的共享资源。而用户级互斥保护了用户程序中的共享资源。

python中提供了lock机制来实现线程之间的互斥。当线程通过lock.acquire获得lock之后,子线程会因为等待lock而挂起,直到主线程释放lock之后才会被Python的线程调度机制唤醒。

在线程执行过程中如果出现需要等待另一个lock资源的时候,需要将GIL转交给其他等待GIL的线程以避免死锁。

知识共享许可协议
本文 由 cococo点点 创作,采用 知识共享 署名-非商业性使用-相同方式共享 3.0 中国大陆 许可协议进行许可。欢迎转载,请注明出处:
转载自:cococo点点 http://www.cnblogs.com/coder2012


相关文章
|
13天前
|
安全 Java 数据处理
Python网络编程基础(Socket编程)多线程/多进程服务器编程
【4月更文挑战第11天】在网络编程中,随着客户端数量的增加,服务器的处理能力成为了一个重要的考量因素。为了处理多个客户端的并发请求,我们通常需要采用多线程或多进程的方式。在本章中,我们将探讨多线程/多进程服务器编程的概念,并通过一个多线程服务器的示例来演示其实现。
|
23天前
|
算法 数据处理 Python
Python并发编程:解密异步IO与多线程
本文将深入探讨Python中的并发编程技术,重点介绍异步IO和多线程两种常见的并发模型。通过对比它们的特点、适用场景和实现方式,帮助读者更好地理解并发编程的核心概念,并掌握在不同场景下选择合适的并发模型的方法。
|
1月前
|
安全 Java 关系型数据库
深入探究Python的多线程与异步编程:实战与最佳实践
【2月更文挑战第1天】 深入探究Python的多线程与异步编程:实战与最佳实践
138 0
|
1月前
|
缓存 负载均衡 安全
在Python中,如何使用多线程或多进程来提高程序的性能?
【2月更文挑战第17天】【2月更文挑战第50篇】在Python中,如何使用多线程或多进程来提高程序的性能?
|
1月前
|
安全 Python
Python中的并发编程:多线程与多进程技术探究
本文将深入探讨Python中的并发编程技术,重点介绍多线程和多进程两种并发处理方式的原理、应用场景及优缺点,并结合实例分析如何在Python中实现并发编程,以提高程序的性能和效率。
|
1月前
|
数据采集 存储 Java
「多线程大杀器」Python并发编程利器:ThreadPoolExecutor,让你一次性轻松开启多个线程,秒杀大量任务!
「多线程大杀器」Python并发编程利器:ThreadPoolExecutor,让你一次性轻松开启多个线程,秒杀大量任务!
|
1月前
|
安全 调度 Python
Python中如何实现多线程?请举例说明。
Python中如何实现多线程?请举例说明。
14 0
|
1月前
|
Python
Python中的并发编程与多线程
在当今高并发的网络应用环境中,如何充分利用计算资源来提高程序的执行效率是一个关键问题。本文将探讨Python中的并发编程技术,重点介绍了多线程的使用方法和注意事项,帮助读者更好地理解并发编程在Python中的应用。
|
7天前
|
调度 Python
Python多线程、多进程与协程面试题解析
【4月更文挑战第14天】Python并发编程涉及多线程、多进程和协程。面试中,对这些概念的理解和应用是评估候选人的重要标准。本文介绍了它们的基础知识、常见问题和应对策略。多线程在同一进程中并发执行,多进程通过进程间通信实现并发,协程则使用`asyncio`进行轻量级线程控制。面试常遇到的问题包括并发并行混淆、GIL影响多线程性能、进程间通信不当和协程异步IO理解不清。要掌握并发模型,需明确其适用场景,理解GIL、进程间通信和协程调度机制。
27 0
|
30天前
|
并行计算 Python
Python中的并发编程:多线程与多进程的比较
在Python编程中,实现并发操作是提升程序性能的重要手段之一。本文将探讨Python中的多线程与多进程两种并发编程方式的优劣及适用场景,帮助读者更好地选择合适的方法来提高程序运行效率。

热门文章

最新文章