I. Introduction
In Python's multi-threaded and multi-process programming, join()
and Event
are both tools used to control the synchronization relationship between threads or processes. Their functions are similar, but there are still some differences.
2. Concept
1. join()
join()
A method is a method of a thread or process instance that blocks the current calling thread or process until the thread or process completes execution before continuing to execute subsequent code. join()
Methods are often used to wait for the completion of another thread or process. In the parent process, you can use join()
to wait for all child processes to complete before continuing to execute the code of the parent process.
2. Event
Event
It is a thread or process synchronization mechanism, mainly used for communication between threads. A Event
represents an internal flag that can be set or cleared. You can use set()
methods to set the Event flag, and use wait()
the method to wait for the flag to be set. Additionally, clear()
the flag can be cleared using the method.
3. Difference
join()
Instance methods belonging to a thread or process can only be used in the current thread or process,Event
and can be shared across threads or processes.join()
The function is to wait for the thread or process to complete execution in order to continue executing subsequent code;Event
the function is to synchronize and communicate between threads to achieve local waiting.
In general, join() is suitable for controlling the execution order between threads or processes, while Event is suitable for realizing synchronization and communication between threads, only partial waiting.
4. Sample code
The following takes threads as an example, and the implementation of processes is similar.
1. Use join()
Wait for a certain thread to finish executing before executing the next step
# -*- coding:utf-8 -*-
import time
import threading
def run(n, event):
for i in range(1000):
print(i, end=' ')
# event.set()
while n > 0:
print('Threading:', n)
n -= 1
time.sleep(1)
event = threading.Event()
if __name__ == '__main__':
print('start threading.')
t = threading.Thread(target=run, args=(5, event))
t.start()
t.join()
# event.wait()
print('end threading...')
Running results: It can be seen that the program has executed all the codes in sequence.
2. Using Events
Wait for part of the code in the thread to execute before executing the following code
# -*- coding:utf-8 -*-
import time
import threading
def run(n, event):
for i in range(1000):
print(i, end=' ')
event.set()
while n > 0:
print('Threading:', n)
n -= 1
time.sleep(1)
event = threading.Event()
if __name__ == '__main__':
print('start threading.')
t = threading.Thread(target=run, args=(5, event))
t.start()
# t.join()
event.wait()
print('end threading.')
Running effect: It can be seen that end threading
the code runs after just waiting for the for loop code to finish running. Explain that Event is only part of the wait.
3. Do not use event and join
code
# -*- coding:utf-8 -*-
import time
import threading
def run(n, event):
for i in range(1000):
print(i, end=' ')
# event.set()
while n > 0:
print('Threading:', n)
n -= 1
time.sleep(1)
event = threading.Event()
if __name__ == '__main__':
print('start threading.')
t = threading.Thread(target=run, args=(5, event))
t.start()
print('end threading.')
Running effect: It can be seen that end threading
it runs before the for loop and does not wait for the for loop code to finish executing.
Attached are several methods to check the number of process threads in Windows
method one
# 获取 WMI 对象
wmi = win32com.client.GetObject("winmgmts:")
# 查询进程信息
process_query = "SELECT * FROM Win32_Process"
process_result = wmi.ExecQuery(process_query)
process_count = len(process_result)
# 查询线程信息
thread_query = "SELECT * FROM Win32_Thread"
thread_result = wmi.ExecQuery(thread_query)
thread_count = len(thread_result)
print("系统进程数量:", process_count)
print("系统线程数量:", thread_count)
Method Two
import psutil
# 获取进程数量
process_count = len(psutil.pids())
print("进程数量:", process_count)
# 获取线程数量
thread_count = 0
for proc in psutil.process_iter(['pid', 'name']):
try:
pinfo = proc.as_dict(attrs=['pid', 'name', 'num_threads'])
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
pass
else:
thread_count += pinfo['num_threads']
print("线程数量:", thread_count)
Method three
import multiprocessing
import threading
print(f"Process {
multiprocessing.current_process().pid}: {
threading.active_count()} threads")
print(f"Process {
threading.current_thread()}: {
threading.active_count()} threads")
print(f"Total threads: {
threading.active_count()}")
print(f"Total processes: {
len(multiprocessing.active_children())}")
V. Summary
- When the main thread or main process is executing, it needs to wait for the sub-thread or sub-process to complete a certain task before continuing to perform subsequent operations. If the join() method is not used, the main thread or main process may exit before the sub-thread or sub-process completes the task, causing program exceptions or incorrect results.
- Both join() and Event are very important synchronization tools in multi-threaded and multi-process programming. They can make the program more reliable and efficient. When the program needs to wait for other threads or processes to complete before continuing execution, you can use the join() method; when the program needs to coordinate and communicate with multiple threads or processes, you can use Event.
Of course, at the same time, please note that when using the join() method, you need to consider synchronization and mutual exclusion issues between threads or processes to avoid deadlocks and race conditions.