Example:
importctypes.wintypesimportgcimportmultiprocessing.poolkernel32=ctypes.WinDLL('kernel32', use_last_error=True)
kernel32.GetCurrentProcess.argtypes= ()
kernel32.GetCurrentProcess.restype=ctypes.wintypes.HANDLEkernel32.GetProcessHandleCount.argtypes= (ctypes.wintypes.HANDLE, ctypes.wintypes.LPDWORD)
kernel32.GetProcessHandleCount.restype=ctypes.wintypes.BOOLdefhandle_count():
# Pseudo-handle that doesn't need to be closedhproc=kernel32.GetCurrentProcess()
handle_count=ctypes.wintypes.DWORD()
ifnotkernel32.GetProcessHandleCount(hproc, ctypes.byref(handle_count)):
raisectypes.WinError(ctypes.get_last_error())
returnhandle_count.valuedeffunc():
pool=multiprocessing.pool.Pool(1)
pool.terminate()
pool.join()
pool.close()
pool=Nonegc.collect()
defmain():
print("Initial handle count:", handle_count())
for_inrange(4):
func()
print("Handle count:", handle_count())
if__name__=="__main__":
main()Output with Python 3.16 on Windows:
Initial handle count: 116
Handle count: 123
Handle count: 127
Handle count: 131
Handle count: 135
I discovered the issue while working on PR gh-154140 which detects leaks of Windows handles in the Python test suite.
Linked PRs
Example:
Output with Python 3.16 on Windows:
I discovered the issue while working on PR gh-154140 which detects leaks of Windows handles in the Python test suite.
Linked PRs