Python多线程

发布时间 2023-08-26 10:45:33作者: 大树咖啡

当进行多线程编程时,涉及到以下几个关键概念和操作:

1. **创建多线程**:

使用 `threading.Thread` 类可以创建新的线程。通过传递一个函数(或可调用对象)作为参数给线程类,这个函数将成为线程的执行体。

import threading
def worker():
    print("Worker thread")

thread = threading.Thread(target=worker)

2. **主线程**:

主线程是程序启动时默认创建的线程。它是第一个开始执行的线程,通常用于初始化、调度和管理其他线程。

3. **阻塞线程**:

在多线程环境中,有时需要等待其他线程完成某些操作,或者等待一段时间后再继续执行。可以使用 `thread.join()` 方法来阻塞当前线程,直到指定的线程执行完毕。

thread.join()  # 阻塞当前线程,直到 thread 执行完毕

4. **判断线程是否活动**:

使用 `threading.Thread.is_alive()` 方法可以判断一个线程是否处于活动状态(正在执行)。

if thread.is_alive():
    print("Thread is still active")

5. **线程同步**:

在多线程环境中,由于多个线程可能共享相同的资源,可能会导致竞争条件和数据不一致问题。为了避免这些问题,可以使用锁(`threading.Lock`)等同步机制来保护共享资源。

lock = threading.Lock()

def worker():
    with lock:
        # 保护共享资源的代码块

创建多个线程的两种方法:

1. **创建线程实例**:

通过创建多个 `threading.Thread` 类的实例来创建多个线程。

thread1 = threading.Thread(target=worker1)
thread2 = threading.Thread(target=worker2)

使用 threading.Thread 类创建多线程时,可以传递一些参数来控制线程的行为和执行。以下是 threading.Thread 构造函数中一些重要参数的含义:

  1. target:

    • 这是一个必需的参数,用于指定线程要执行的函数或可调用对象。线程将会运行这个函数。
    • 示例:threading.Thread(target=my_function)
  2. args:

    • 这是一个可选参数,是一个元组(tuple),用于传递给目标函数的参数。如果目标函数需要参数,可以使用这个参数进行传递。
    • 示例:threading.Thread(target=my_function, args=(arg1, arg2))
  3. kwargs:

    • 这是一个可选参数,是一个字典(dictionary),用于传递给目标函数的关键字参数。
    • 示例:threading.Thread(target=my_function, kwargs={"key1": value1, "key2": value2})
  4. name:

    • 这是一个可选参数,用于给线程指定一个名字,以便于标识和区分不同的线程。
    • 示例:threading.Thread(target=my_function, name="MyThread")
  5. daemon:

    • 这是一个可选参数,默认为 False。如果设置为 True,则表示将线程设置为守护线程,即主线程退出时会自动终止守护线程,而不管它是否完成。
    • 示例:threading.Thread(target=my_function, daemon=True)
  6. group:

    • 这是一个可选参数,用于设置线程组。通常情况下,不需要显式地指定线程组。
  7. kwargs:

    • 这是一个可选参数,用于传递额外的关键字参数给 Thread 类的构造函数。

下面是一个示例,演示了如何创建一个带参数的多线程:

import threading

def print_numbers(start, end):
    for i in range(start, end):
        print(i)

thread = threading.Thread(target=print_numbers, args=(1, 6))
thread.start()
thread.join()

 

2. **继承 Thread 类**:

创建一个继承自 `threading.Thread` 类的子类,重写 `run()` 方法,然后通过实例化子类来创建线程。

class MyThread(threading.Thread):
    def run(self):
        # 线程执行的内容

thread1 = MyThread()
thread2 = MyThread()

综合以上概念,以下是一个完整的示例,演示了如何创建多个线程、主线程的行为、阻塞线程、判断线程是否活动以及使用锁进行线程同步:

import threading
import time

def worker():
    print(f"Worker thread started by {threading.current_thread().name}")
    time.sleep(2)
    print(f"Worker thread finished by {threading.current_thread().name}")

lock = threading.Lock()

def synchronized_worker():
    with lock:
        print(f"Synchronized worker thread started by {threading.current_thread().name}")
        time.sleep(2)
        print(f"Synchronized worker thread finished by {threading.current_thread().name}")

thread1 = threading.Thread(target=worker, name="Thread 1")
thread2 = threading.Thread(target=worker, name="Thread 2")

synchronized_thread1 = threading.Thread(target=synchronized_worker, name="Synchronized Thread 1")
synchronized_thread2 = threading.Thread(target=synchronized_worker, name="Synchronized Thread 2")

print("Main thread started")
thread1.start()
thread2.start()

synchronized_thread1.start()
synchronized_thread2.start()

thread1.join()
thread2.join()

synchronized_thread1.join()
synchronized_thread2.join()

print("Main thread finished")

在这个示例中,主线程启动了多个普通线程和带锁的线程。主线程会等待所有线程都完成后再继续执行。注意,在实际编程中,需要根据具体情况使用适当的线程同步机制来保护共享资源。