如何创新Python虚拟机线程
创始人
2024-06-23 20:21:03
0

一些开发人员明确指示Python虚拟机创建新的线程,Python就能意识到用户需要多线程的支持,如果没有前期的这些支持,不知道Python虚拟机能不能顺利的发展下去。

Python虚拟机的thread module所提供的接口中,一定不能少的肯定是创建线程的接口,倘若没有这个接口,生活还有什么意义呢J?在上面的thread1.py中,我们正是通过其提供的start_new_thread创建了一个崭新的线程。好,我们就进入这个start_new_ thread,看看Python是如何进行创世纪的工作的:

  1. [thread_nt.h]  
  2.  
  3. int PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)  
  4.  
  5. {  
  6.  
  7.     int success ;  
  8.  
  9.     success = aLock && EnterNonRecursiveMutex((PNRMUTEX) aLock, (waitflag 
  10.  
  11.        == 1 ? INFINITE : 0)) == WAIT_OBJECT_0 ;  
  12.  
  13.     return success;  
  14.  
  15. }  
  16.  
  17. DWORD EnterNonRecursiveMutex(PNRMUTEX mutex, BOOL wait)  
  18.  
  19. {  
  20.  
  21.     /* Assume that the thread waits successfully */  
  22.  
  23.     DWORD ret;  
  24.  
  25.     /* InterlockedIncrement(&mutex->owned) == 0 means that no thread  
  26.  
  27.         currently owns the mutex */  
  28.  
  29.     if (!wait)  
  30.  
  31.     {  
  32.  
  33.         if (InterlockedCompareExchange((PVOID *)&mutex->owned, (PVOID)0,  
  34.  
  35.               (PVOID)-1) != (PVOID)-1)  
  36.  
  37.             return WAIT_TIMEOUT ;  
  38.  
  39.         ret = WAIT_OBJECT_0 ;  
  40.  
  41.     }  
  42.  
  43.     else  
  44.  
  45.         ret = InterlockedIncrement(&mutex->owned) ?  
  46.  
  47.             /* Some thread owns the mutex, let's wait... */  
  48.  
  49.             WaitForSingleObject(mutex->hevent, INFINITE) : WAIT_OBJECT_0 ;  
  50.  
  51.     mutex->thread_id = GetCurrentThreadId() ; /* We own it */  
  52.  
  53.     return ret ;  
  54.  
  55. }  

在代码清单中,我们注意到boot->interp中保存了Python的PyInter- preterState对象,这个对象中携带了Python的module pool这样的全局信息,Python中所有的thread都会共享这些全局信息。

关于代码清单15-1的[2]处所示的多线程环境的初始化动作,有一点需要特别说明,当Python启动时,是并不支持多线程的。换句话说,Python中支持多线程的数据结构以及GIL都是没有创建的,Python之所以有这种行为是因为大多数的Python程序都不需要多线程的支持。

假如一个简单地统计词频的Python脚本中居然出现了多线程,面对这样的代码,我们一定都会抓狂的J。
对多线程的支持并非是没有代价的。最简单的一点,如果激活多线程机制,而执行的Python程序中并没有多线程,那么在100条指令之后,Python虚拟机同样会激活线程的调度。

而如果不激活多线程,Python虚拟机则不用做这些无用功。所以Python选择了让用户激活多线程机制的策略。在Python虚拟机启动时,多线程机制并没有被激活,它只支持单线程,一旦用户调用thread.start_new_thread。

明确指示Python虚拟机创建新的线程,Python就能意识到用户需要多线程的支持,这个时候,Python虚拟机会自动建立多线程机制需要的数据结构、环境以及那个至关重要的GIL。

在这里,我们终于看到了Python中多线程机制的平台相关性,在Python25\Python目录下,有一大批thread_***.h这样的文件。这些文件中,包装了不同操作系统的原生线程,并通过统一的接口暴露给Python,比如这里的PyThread_allocate_lock就是这样一个接口。

我们这里的thread_nt.h中包装的是Win32平台的原生thread,在本章中后面的代码剖析中,还会有大量与平台相关的代码,我们都以Win32平台为例。在PyThread_allocate_lock中,与PyEval_InitThreads非常类似的,它会检查一个initialized的变量,如果说GIL指示着Python的多线程环境是否已经建立。

那么这个initialized变量就指示着为了使用底层平台所提供的原生thread,必须的初始化动作是否完成。这些必须的初始化动作通常都是底层操作系统所提供的API,不同的操作系统可能需要不同的初始化动作。

【编辑推荐】

  1. 有关Python系统文件进行介绍指导
  2. 如何正确的使用Python函数
  3. Python 构建工具进行详细介绍分析
  4. PythonAndroid浅析Python优势所在
  5. 如何使用Python模块解析配置文件?

相关内容

热门资讯

PHP新手之PHP入门 PHP是一种易于学习和使用的服务器端脚本语言。只需要很少的编程知识你就能使用PHP建立一个真正交互的...
网络中立的未来 网络中立性是什... 《牛津词典》中对“网络中立”的解释是“电信运营商应秉持的一种原则,即不考虑来源地提供所有内容和应用的...
各种千兆交换机的数据接口类型详... 千兆交换机有很多值得学习的地方,这里我们主要介绍各种千兆交换机的数据接口类型,作为局域网的主要连接设...
粉嫩如何诠释霸道 东芝M805... “霸道粉”是个什么玩意东芝M805拿过来的时候,笔者扑哧笑了,不是笑这款笔记本,而是笑这款产品的颜色...
什么是大数据安全 什么是大数据... 在《为什么需要大数据安全分析》一文中,我们已经阐述了一个重要观点,即:安全要素信息呈现出大数据的特征...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
全面诠释网络负载均衡 负载均衡的出现大大缓解了服务器的压力,更是有效的利用了资源,提高了效率。那么我们现在来说一下网络负载...
如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
30分钟搞定iOS自定义相机 最近公司的项目中用到了相机,由于不用系统的相机,UI给的相机切图,必须自定义才可以。就花时间简单研究...
Intel将Moblin社区控... 本周二,非营利机构Linux基金会宣布,他们将担负起Moblin社区的管理工作,而这之前,Mobli...