Issue44436
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2021-06-16 15:43 by vstinner, last changed 2022-04-11 14:59 by admin. This issue is now closed.
Messages (5) | |||
---|---|---|---|
msg395939 - (view) | Author: STINNER Victor (vstinner) * | Date: 2021-06-16 15:43 | |
_thread.start_new_thread() is implemented by calling _beginthreadex(). Currently, when the thread completes: PyThread_exit_thread() is called which calls "_endthreadex(0)" on Windows. I proposed to no longer call it explicitly in bpo-44434. _endthreadex() documentation says that the thread handle must be closed explicitly (with CloseHandle()), same applies for ExitThread(). "Unlike _endthread, the _endthreadex function does not close the thread handle, thereby allowing other threads to block on this one without fear that the handle will be freed out from under the system." _endthread() closes the thread handle, but Python uses _endthreadex(). Should Python be modified to close explicitly the thread handle once the thread terminated? _endthread() and _endthreadex() documentation: https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/endthread-endthreadex?view=msvc-160 Example closing the thread handle in the thread which created the thread: https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/beginthread-beginthreadex?view=msvc-160 Simplified code: --- hThread = (HANDLE)_beginthreadex( NULL, 0, &SecondThreadFunc, NULL, 0, &threadID ); WaitForSingleObject( hThread, INFINITE ); CloseHandle( hThread ); --- Would it be safe to close the handle just after PyThread_start_new_thread() success? Or should it be done in the C function thread_run(), just before existing, CloseHandle(GetCurrentThread())? To debug this issue, GetHandleInformation() can be used to check if the handle is still open or not. For example, call os.get_handle_inheritable(handle) in Python. |
|||
msg395944 - (view) | Author: Eryk Sun (eryksun) * | Date: 2021-06-16 15:56 | |
> Would it be safe to close the handle just after PyThread_start_new_thread() > success? We already close the handle in PyThread_start_new_thread() in Python/thread_nt.h: if (hThread == 0) { // ... } else { dprintf(("%lu: PyThread_start_new_thread succeeded: %p\n", PyThread_get_thread_ident(), (void*)hThread)); CloseHandle(hThread); } |
|||
msg395945 - (view) | Author: STINNER Victor (vstinner) * | Date: 2021-06-16 15:57 | |
> CloseHandle(GetCurrentThread()) This is useless. GetCurrentThread() returns a pseudo handle. The GetCurrentThread() documentation says: "The pseudo handle need not be closed when it is no longer needed. Calling the CloseHandle function with this handle has no effect." |
|||
msg395947 - (view) | Author: STINNER Victor (vstinner) * | Date: 2021-06-16 16:01 | |
> [Windows] _thread.start_new_thread() should close the thread handle So far, I'm not convinced that Python must be changed. I modified my Python locally so thread_run() writes GetCurrentThread() to stderr. Example: --- SLEEP = 5 import ctypes import _thread import time import os HANDLE = ctypes.c_voidp DWORD = ctypes.c_ulong ResumeThread = ctypes.windll.kernel32.ResumeThread ResumeThread.argtypes = (HANDLE,) ResumeThread.restype = DWORD SuspendThread = ctypes.windll.kernel32.SuspendThread SuspendThread.argtypes = (HANDLE,) SuspendThread.restype = DWORD def func(): time.sleep(SLEEP) print("--thread exit--") def check_handle(handle): x = SuspendThread(handle) print(f"SuspendThread({handle}) -> {x}") x = ResumeThread(handle) print(f"ResumeThread({handle}) -> {x}") handle = _thread.start_new_thread(func, ()) print(f"start_new_thread() -> {handle}") check_handle(handle) time.sleep(SLEEP+1) check_handle(handle) --- Output: --- start_new_thread() -> 2436 SuspendThread(2436) -> 4294967295 ResumeThread(2436) -> 4294967295 thread_run: GetCurrentThread() -> -2 --thread exit-- SuspendThread(2436) -> 4294967295 ResumeThread(2436) -> 4294967295 --- It seems like the handle returned by _beginthreadex() cannot be used with SuspendThread() or ResumeThread(): both fail. GetHandleInformation() also fails on this handle (I tried os.get_handle_inheritable()). |
|||
msg395948 - (view) | Author: STINNER Victor (vstinner) * | Date: 2021-06-16 16:03 | |
Eryk: > We already close the handle in PyThread_start_new_thread() in Python/thread_nt.h Oh right! I completely missed this call. Thanks for double checking the issue ;-) I close the issue as "not a bug". |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-11 14:59:46 | admin | set | github: 88602 |
2021-06-16 16:03:07 | vstinner | set | status: open -> closed resolution: not a bug messages: + msg395948 stage: resolved |
2021-06-16 16:01:21 | vstinner | set | messages: + msg395947 |
2021-06-16 15:57:49 | vstinner | set | messages: + msg395945 |
2021-06-16 15:56:25 | eryksun | set | messages: + msg395944 |
2021-06-16 15:43:23 | vstinner | create |