如何进行建立Python主线程?

开发 后端
本文对Python主线程进行选择,IDE选择及编码的解决方案进行了一番详细的描述,实为Python初学者必读的Python学习经验心得。

Python里如果你建立一个程序,就是一个进程,其中包含一个线程,这个就是主线程,而是为了提高资源使用效率来提高系统的效率,希望大家能够再次学到自己想要的信息。

从这里可以看到,当一个线程开始等待GIL时,其owned就会被增加1。显然我们可以猜测,当一个线程最终释放GIL时,一定会将GIL的owned减1,这样当所有需要GIL的线程都最终释放了GIL之后,owned会再次变为-1,意味着GIL再次变为可用。

为了清晰地展示这一点,我们现在就来看看PyThread_aquire_lock的逆运算,PyThread_release_lock每一个将从运行转态转为等待状态的线程都会在被挂起之前调用它以释放对GIL的占有。

  1. [thread_nt.h]  
  2.  
  3. PNRMUTEX AllocNonRecursiveMutex(void)  
  4.  
  5. {  
  6.  
  7.     PNRMUTEX mutex = (PNRMUTEX)malloc(sizeof(NRMUTEX)) ;  
  8.  
  9.     if(mutex && !InitializeNonRecursiveMutex(mutex)) {  
  10.  
  11.             free(mutex);  
  12.  
  13.             Mutex = NULL;  
  14.  
  15.     }  
  16.  
  17.     return mutex ;  
  18.  
  19. }  
  20.  
  21. BOOL InitializeNonRecursiveMutex(PNRMUTEX mutex)  
  22.  
  23. {  
  24.  
  25.     ……  
  26.  
  27.     mutex->owned = -1 ;  /* No threads have entered NonRecursiveMutex */  
  28.  
  29.     mutex->thread_id = 0 ;  
  30.  
  31.     mutex->hevent = CreateEvent(NULL, FALSE, FALSE, NULL) ;  
  32.  
  33.     return mutex->hevent != NULL ;  /* TRUE if the mutex is created */  
  34.  
  35. }  

最终,一个线程在释放GIL时,会通过SetEvent通知所有在等待GIL的hevent这个Event内核对象的线程,结合前面的分析,如果这时候有线程在等待GIL的hevent,那么将被操作系统唤醒。

这就是我们在前面介绍的Python将线程调度的第二个难题委托给操作系统来实现的机制。到了这时,调用PyEval_InitThread的线程(也就是Python主线程)已经成功获得了GIL。***会调用PyThread_get_thread_ident()。

通过Win32的API:GetCurrent- ThreadId,获得当前Python主线程的id,并将其赋给main_thread,main_thread是一个静态全局变量,专职存储Python主线程的线程id,用以判断一个线程是否是Python主线程

在完成了多线程环境的初始化之后,Python会开始创建底层平台的原生thread,以thread1.py为例,这个原生thread将执行threadProc所定义的操作。从现在开始,为了描述的清晰性,我们将Python主线程,也就是调用thread_PyThread_start_new_thread创建新的线程的线程称为主线程,而将与threadProc对应的原生thread称之为子线程。现在我们来看看一个子线程是如何被创建的。

  1. static PyObject* thread_PyThread_start_new_thread(PyObject *self, PyObject  
  2.  
  3.   *fargs)  
  4.  
  5. {  
  6.  
  7.     PyObject *func, *args, *keyw = NULL;  
  8.  
  9.     struct bootstate *boot;  
  10.  
  11.     long ident;  
  12.  
  13.     PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3, &func, &args, &keyw);  
  14.  
  15.     //[1]:创建bootstate结构  
  16.  
  17.     boot = PyMem_NEW(struct bootstate, 1);  
  18.  
  19.     boot->interp = PyThreadState_GET()->interp;  
  20.  
  21.     boot->funcfunc = func;  
  22.  
  23.     boot->argsargs = args;  
  24.  
  25.     boot->keywkeyw = keyw;  
  26.  
  27.     //[2]:初始化多线程环境  
  28.  
  29.     PyEval_InitThreads(); /* Start the interpreter's thread-awareness */  
  30.  
  31.     //[3]:创建线程  
  32.  
  33.     ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);  
  34.  
  35.     return PyInt_FromLong(ident);  
  36.  
  37. [thread.c]  
  38.  
  39. /* Support for runtime thread stack size tuning.  
  40.  
  41.    A value of 0 means using the platform's default stack size  
  42.  
  43.    or the size specified by the THREAD_STACK_SIZE macro. */  
  44.  
  45. static size_t _pythread_stacksize = 0;  
  46.  
  47. [thread_nt.h]  
  48.  
  49. long PyThread_start_new_thread(void (*func)(void *), void *arg)  
  50.  

Python主线程通过调用PyThread_start_new_thread完成创建子线程的工作。为了清晰地理解PyThread_start_new_thread的工作,我们需要特别注意该函数的参数。从thread_ PyThread_start_new_thread中可以看到,这里的func实际上是函数t_bootstrap,而arg则是在thread_PyThread_start_new_thread中创建的bootstate结构体boot。在boot中,保存着Python程序(thread1.py)中所定义的线程的信息。

【编辑推荐】

  1. 如何使Python嵌入C++应用程序?
  2. 深入探讨Ruby与Python语法比较
  3. Python学习资料介绍分享
  4. Python学习经验谈:版本、IDE选择及编码解 决方案
  5. 浅析Python的GIL和线程安全
责任编辑:chenqingxiang 来源: 博客园
相关推荐

2010-02-02 16:47:12

Python主线程

2010-03-10 19:34:45

Python主线程

2010-07-01 13:29:08

vsftpd

2010-02-22 16:05:40

Python配置

2010-02-01 10:21:36

Python编码转换

2024-07-08 08:38:37

Python游戏开发

2010-02-03 13:55:51

Python 代码

2010-02-26 15:37:11

Python主线程

2010-02-01 14:48:43

2010-02-01 18:20:17

Python 多重继承

2010-03-11 17:38:20

Python中文

2010-03-15 15:11:50

Python列表

2010-03-16 10:32:36

Java线程拨号器

2010-03-01 16:32:36

Python语言

2010-02-22 17:12:34

Python对象

2010-03-09 18:14:55

Python sock

2010-03-01 11:06:52

Python 调试器

2010-02-01 16:22:36

Python字符串操作

2010-03-15 15:45:15

Python编程语言

2010-03-17 18:21:54

Java多线程静态数据
点赞
收藏

51CTO技术栈公众号