Python - The difference between join and event in multi-threading, multi-process and not using join and event

I. Introduction

In Python's multi-threaded and multi-process programming, join()and Eventare 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

EventIt is a thread or process synchronization mechanism, mainly used for communication between threads. A Eventrepresents 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, Eventand 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; Eventthe 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.
Insert image description here

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 threadingthe code runs after just waiting for the for loop code to finish running. Explain that Event is only part of the wait.
Insert image description here

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 threadingit runs before the for loop and does not wait for the for loop code to finish executing.
Insert image description here

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.

Guess you like

Origin blog.csdn.net/qq_43030934/article/details/132301123