Python 多线程threading与多线程中join()的用法

Python 多线程threading与多线程中join()的用法

Python 多线程threading与多线程中join()的用法

1. 简介

多线程是指在一个程序中同时运行多个线程,每个线程执行不同的任务。在Python中,我们可以使用threading模块来实现多线程编程。threading模块提供了创建和管理线程的功能,使得我们能够更好地利用多核处理器的能力,提高程序的性能。

join()threading.Thread类中的一个方法,用于阻塞当前线程,并等待调用该方法的线程执行完毕后再继续执行。本文将详细讲解threading模块的用法和join()方法的使用。

在学习本文之前,我们需要对多线程的概念和基本用法有一定了解。

2. Python多线程编程基础

在Python中,要使用多线程,首先需要导入threading模块。然后,我们需要创建一个Thread类的实例,将需要执行的函数作为参数传递给Thread类的构造方法,并调用start()方法启动线程。

下面是一个简单的例子,演示了如何使用threading模块创建并启动线程:

import threading
import time

# 定义一个线程要执行的函数
def thread_func():
    # 线程执行的代码
    for i in range(5):
        print(f"Thread {threading.current_thread().name}: {i}")
        time.sleep(1)

# 创建线程实例并启动线程
thread = threading.Thread(target=thread_func)
thread.start()

# 主线程执行的代码
for i in range(5):
    print(f"Main Thread: {i}")
    time.sleep(1)

代码运行结果:

Thread Thread-1: 0
Main Thread: 0
Main Thread: 1
Thread Thread-1: 1
Main Thread: 2
Thread Thread-1: 2
Main Thread: 3
Thread Thread-1: 3
Main Thread: 4
Thread Thread-1: 4

上述代码中,我们创建了一个名为thread的线程实例,并指定thread_func函数作为线程要执行的代码。然后我们调用thread.start()方法启动线程。在主线程中,我们也有一些代码需要执行,因此主线程和子线程会同时执行。输出结果显示,主线程和子线程交替执行。

3. join()的用法

join()threading.Thread类的一个方法,用于阻塞当前线程,并等待调用该方法的线程执行完毕后再继续执行。如果调用join()方法的线程已经结束,则join()方法立即返回。

下面是一个示例代码,演示了join()方法的用法:

import threading
import time

# 定义一个线程要执行的函数
def thread_func():
    # 线程执行的代码
    for i in range(5):
        print(f"Thread {threading.current_thread().name}: {i}")
        time.sleep(1)

# 创建线程实例并启动线程
thread = threading.Thread(target=thread_func)
thread.start()

# 阻塞当前线程,并等待子线程执行完毕
thread.join()

# 主线程执行的代码
for i in range(5):
    print(f"Main Thread: {i}")
    time.sleep(1)

代码运行结果:

Thread Thread-1: 0
Thread Thread-1: 1
Thread Thread-1: 2
Thread Thread-1: 3
Thread Thread-1: 4
Main Thread: 0
Main Thread: 1
Main Thread: 2
Main Thread: 3
Main Thread: 4

上述代码中,我们在主线程中调用了thread.join()方法,这会阻塞主线程,并等待子线程执行完毕后再继续执行。因此,输出结果显示先打印子线程的输出,然后才打印主线程的输出。

如果我们不调用join()方法,主线程和子线程将会并发执行。下面是一个示例代码:

import threading
import time

# 定义一个线程要执行的函数
def thread_func():
    # 线程执行的代码
    for i in range(5):
        print(f"Thread {threading.current_thread().name}: {i}")
        time.sleep(1)

# 创建线程实例并启动线程
thread = threading.Thread(target=thread_func)
thread.start()

# 主线程执行的代码
for i in range(5):
    print(f"Main Thread: {i}")
    time.sleep(1)

代码运行结果:

Main Thread: 0
Thread Thread-1: 0
Main Thread: 1
Main Thread: 2
Thread Thread-1: 1
Main Thread: 3
Thread Thread-1: 2
Main Thread: 4
Thread Thread-1: 3
Thread Thread-1: 4

在上述代码中,我们没有调用join()方法,因此主线程和子线程交替执行,输出结果显示先打印主线程的输出,然后才打印子线程的输出。

4. join()方法的参数

join()方法还可以接受一个可选的超时参数。超时参数表示最长等待多少秒,如果超过这个时间线程还没有执行完毕,则会继续执行调用join()方法的线程。

下面是一个示例代码,演示了join()方法的超时参数的用法:

import threading

# 定义一个线程要执行的函数
def thread_func():
    # 线程执行的代码
    import time

    for i in range(3):
        print(f"Thread {threading.current_thread().name}: {i}")
        time.sleep(1)

# 创建线程实例并启动线程
thread = threading.Thread(target=thread_func)
thread.start()

# 阻塞当前线程,并等待子线程执行完毕,最长只等待2秒
thread.join(2)

# 主线程执行的代码
for i in range(3):
    print(f"Main Thread: {i}")

代码运行结果:

Thread Thread-1: 0
Thread Thread-1: 1
Main Thread: 0
Thread Thread-1: 2
Main Thread: 1
Main Thread: 2

在上述代码中,我们在join()方法中传入了2作为超时参数,即最长等待2秒。子线程需要执行3次循环,每次循环等待1秒,因此子线程总共需要执行3秒。而主线程只会执行3次循环,每次循环等待不到1秒,因此不会被子线程的join()方法阻塞。所以,输出结果只有子线程的前两次循环和主线程的输出。

5. join()方法的应用场景

join()方法通常用于在主线程中等待子线程完成某个任务后再继续执行,或者在一个线程中等待其他线程的结果才能继续执行。下面是一些常见的应用场景:

等待子线程完成任务

当主线程需要等待所有子线程完成某个任务后再继续执行时,可以使用join()方法。

import threading

# 定义一个线程要执行的函数
def thread_func():
    # 线程执行的代码
    import time

    for i in range(3):
        print(f"Thread {threading.current_thread().name}: {i}")
        time.sleep(1)

# 创建线程实例并启动线程
threads = []
for i in range(3):
    thread = threading.Thread(target=thread_func)
    threads.append(thread)
    thread.start()

# 阻塞主线程,等待所有子线程执行完毕
for thread in threads:
    thread.join()

# 主线程执行的代码
print("All threads have finished.")

在上述代码中,我们创建了三个子线程并启动它们。然后,在主线程中遍历子线程列表,并调用每个子线程的join()方法,以阻塞主线程并等待子线程执行完毕。最后,主线程打印一条消息说明所有子线程已经完成。

依次执行线程

有时,我们需要在一个线程结束后再启动下一个线程。可以使用join()方法来实现线程的按顺序执行。

import threading

# 定义一个线程要执行的函数
def thread_func(name):
    # 线程执行的代码
    import time

    for i in range(3):
        print(f"Thread {name}: {i}")
        time.sleep(1)

# 创建线程实例并启动线程
thread1 = threading.Thread(target=thread_func, args=("A",))
thread2 = threading.Thread(target=thread_func, args=("B",))
thread3 = threading.Thread(target=thread_func, args=("C",))

# 启动线程1
thread1.start()
thread1.join()

# 启动线程2
thread2.start()
thread2.join()

# 启动线程3
thread3.start()
thread3.join()

# 主线程执行的代码
print("All threads have finished.")

在上述代码中,我们依次启动线程1、线程2和线程3,并分别调用join()方法来保证线程按照顺序执行。主线程在所有子线程执行完毕后打印一条消息。

等待其他线程结果

有时候,一个线程需要等待其他几个线程的结果才能继续执行。可以使用join()方法来实现线程间的协作。

import threading

results = []

def worker1():
    import time
    result = "Worker 1 result"
    time.sleep(3)
    results.append(result)

def worker2():
    import time
    result = "Worker 2 result"
    time.sleep(5)
    results.append(result)

# 创建线程实例并启动线程
thread1 = threading.Thread(target=worker1)
thread2 = threading.Thread(target=worker2)

# 启动线程1
thread1.start()

# 启动线程2
thread2.start()

# 等待线程1和线程2执行完毕
thread1.join()
thread2.join()

# 主线程获取线程1和线程2的结果
print(f"Worker 1 result: {results[0]}")
print(f"Worker 2 result: {results[1]}")

在上述代码中,worker1()worker2()函数代表两个工作线程,它们分别模拟了需要一定时间才能完成的耗时任务。主线程需要等待线程1和线程2执行完毕后才能获取它们的结果。通过调用join()方法,主线程被阻塞直到线程1和线程2结束。然后,主线程获取工作线程的结果并打印输出。

总结

本文详细介绍了Python threading模块的用法和join()方法的使用。我们学习了如何通过threading.Thread类来创建和启动线程,以及使用join()方法来阻塞当前线程并等待其他线程执行完毕后再继续执行。join()方法的超时参数可以设置等待的最长时间。通过合理使用多线程和join()方法,我们可以实现并发执行任务、按顺序执行线程和线程间的协作。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程