Python Treading
## Python3.x Python threading Module
Python's `threading` module is one of the standard libraries for implementing multi-threaded programming. Multi-threading allows a program to execute multiple tasks at the same time, thereby improving the program's efficiency and responsiveness.
The `threading` module provides tools for creating and managing threads, making it easy for developers to write concurrent programs.
### What is a Thread?
You can think of a thread as an employee in an office:
* A single-threaded program is like having only one employee who must sequentially complete all tasks such as printing documents, replying to emails, making coffee, etc.
* A multi-threaded program is like having multiple employees who can perform different tasks **simultaneously**, greatly improving work efficiency.
In computer science:
* **Process**: A running program with independent memory space (for example, the browser and music player you have open at the same time are two processes).
* **Thread**: An independent execution flow within a process, which is the basic unit of CPU scheduling. All threads within the same process **share the process's memory space** (such as global variables).
### Why Use Multi-threading?
In a single-threaded program, tasks are executed sequentially one after another. If a task needs to wait (for example, waiting for a network response or file reading), the entire program will be blocked until that task is completed. Multi-threading allows the program to continue executing other tasks while waiting for a certain task, thereby improving the overall performance of the program.
### Python's Threads and the Global Interpreter Lock (GIL)
Python has a mechanism called the Global Interpreter Lock (GIL), which ensures that at any given time, only one thread can execute Python bytecode.
**What does this mean?** For CPU-intensive tasks (such as scientific computing, image processing), due to the existence of GIL, multi-threading usually cannot take advantage of multi-core benefits to improve computing speed, and may even become slower due to the overhead of thread switching.
**So, where does Python multi-threading shine?** For I/O-intensive tasks (such as network requests, file reading/writing, waiting for user input), threads release the GIL while waiting for I/O operations to complete, allowing other threads to run. This can significantly improve the overall response speed and efficiency of the program, because while you are waiting for a web page response, the program can go handle another task.
* * *
The first step in using the `threading` module is to import it:
import threading import time # Used to simulate time-consuming operations
The most basic way to create a thread is to use the `threading.Thread` class.
**Syntax explanation:**
thread_obj = threading.Thread(target=function_name, args=(parameter_tuple,))
* **target**: Specifies the function to be executed after the thread starts.
* **args**: Parameters passed to the target function, must be a tuple type. If there is only one parameter, it needs to be written as `(parameter,)`.
### 1. Creating Threads
In Python, threads can be created by either inheriting from the `threading.Thread` class or directly using the `threading.Thread` constructor.
#### Method 1: Inherit from `threading.Thread` Class
## Example
import threading
class MyThread(threading.Thread):
def run(self):
print("Thread started execution")
# Write the code to be executed by the thread here
print("Thread execution ended")
# Create thread instance
thread= MyThread()
# Start thread
thread.start()
# Wait for thread to finish execution
thread.join()
print("Main thread ended")
#### Method 2: Use `threading.Thread` Constructor
## Example
import threading
def my_function():
print("Thread started execution")
# Write the code to be executed by the thread here
print("Thread execution ended")
# Create thread instance
thread=threading.Thread(target=my_function)
# Start thread
thread.start()
# Wait for thread to finish execution
thread.join()
print("Main thread ended")
### 2. Thread Synchronization
In multi-threaded programming, multiple threads may access shared resources at the same time, which can lead to data inconsistency problems. To avoid this, thread synchronization mechanisms such as locks (`Lock`) can be used.
## Example
import threading
# Create a lock object
lock =threading.Lock()
def my_function():
with lock:
print("Thread started execution")
# Write the code to be executed by the thread here
print("Thread execution ended")
# Create thread instances
thread1 =threading.Thread(target=my_function)
thread2 =threading.Thread(target=my_function)
# Start threads
thread1.start()
thread2.start()
# Wait for threads to finish execution
thread1.join()
thread2.join()
print("Main thread ended")
### 3. Inter-thread Communication
Inter-thread communication can be achieved through queues (`Queue`). `Queue` is thread-safe and can safely pass data between multiple threads.
## Example
import threading
import queue
def worker(q):
while not q.empty():
item = q.get()
print(f"Processing item: {item}")
q.task_done()
# Create a queue and fill it with data
q = queue.Queue()
for i in range(10):
q.put(i)
# Create thread instances
thread1 =threading.Thread(target=worker, args=(q,))
thread2 =threading.Thread(target=worker, args=(q,))
# Start threads
thread1.start()
thread2.start()
# Wait for all items in the queue to be processed
q.join()
print("All items processed")
* * *
## Common Classes, Methods, and Attributes
### 1. Core Classes
| Class/Method/Attribute | Description | Example |
| --- | --- | --- |
| **`threading.Thread`** | Thread class, used to create and manage threads | `t = Thread(target=func, args=(1,))` |
| **`threading.Lock`** | Mutex (primitive lock) | `lock = Lock()` |
| **`threading.RLock`** | Reentrant lock (same thread can acquire multiple times) | `rlock = RLock()` |
| **`threading.Event`** | Event object, used for thread synchronization | `event = Event()` |
| **`threading.Condition`** | Condition variable, used for complex thread coordination | `cond = Condition()` |
| **`threading.Semaphore`** | Semaphore, controls the number of concurrent threads | `sem = Semaphore(3)` |
| **`threading.BoundedSemaphore`** | Bounded semaphore (prevents count from exceeding initial value) | `b_sem = BoundedSemaphore(2)` |
| **`threading.Timer`** | Timer thread, delayed execution | `timer = Timer(5.0, func)` |
| **`threading.local`** | Thread-local data (each thread stores independently) | `local_data = threading.local()` |
### 2. Common Thread Object Methods/Attributes
| Method/Attribute | Description | Example |
| --- | --- | --- |
| **`start()`** | Start the thread | `t.start()` |
| **`run()`** | Method executed by the thread (can be overridden) | Override this method in custom class |
| **`join(timeout=None)`** | Block current thread until target thread ends | `t.join()` |
| **`is_alive()`** | Check if thread is running | `if t.is_alive():` |
| **`name`** | Thread name (can be modified) | `t.name = "Worker-1"` |
| **`daemon`** | Daemon thread flag (automatically ends when main thread exits) | `t.daemon = True` |
| **`ident`** | Thread identifier (is `None` when not started) | `print(t.ident)` |
### 3. Common Lock/RLock Methods
| Method | Description | Example |
| --- | --- | --- |
| **`acquire(blocking=True, timeout=-1)`** | Acquire lock (blocking or non-blocking) | `lock.acquire()` |
| **`release()`** | Release lock | `lock.release()` |
| **`locked()`** | Check if lock is held | `if not lock.locked():` |
### 4. Common Event Methods
| Method | Description | Example |
| --- | --- | --- |
| **`set()`** | Set event to true, wake up all waiting threads | `event.set()` |
| **`clear()`** | Reset event to false | `event.clear()` |
| **`wait(timeout=None
YouTip