欢迎访问宙启技术站
智能推送

Python中的线程:常用函数和 实践

发布时间:2023-05-31 17:56:41

Python是一种功能强大的编程语言,其中的线程模块允许使用多个线程同时运行代码。线程在应用程序中处理多个任务或进程时非常有用,但是线程使用不当可能会导致一些问题,如死锁和内存泄漏。在本文中,我们将探讨Python中线程的常用函数和 实践。

常用函数

Python中线程模块的主要函数是Thread()。以下是一些常见的Thread()函数参数:

1. target - 需要在新线程中运行的函数。

2. args - 传递给目标函数的参数的元组。

3. name - 线程的名称。

以下是Thread()函数的示例:

import threading 

def worker(num): 
    """thread worker function""" 
    print('Worker:', num) 

if __name__ == '__main__':
    threads = []
    for i in range(5):
        t = threading.Thread(target=worker, args=(i,))
        threads.append(t)
        t.start()

在上面的示例中,我们定义了一个worker()函数,该函数接受一个参数num,并在执行时打印信息。然后,我们创建了五个不同的线程,每个线程都调用worker()函数,我们将这些线程存储在一个列表中,并使用start()方法启动它们。

实践

1. 使用锁避免竞争条件

当在多个线程中修改共享资源时,可能会遇到竞争条件问题。为了避免这种问题,线程模块提供了锁机制,允许线程在访问共享资源时互斥,从而避免数据损坏或竞争条件。

以下是使用锁的示例:

import threading 

def worker(num, lock):
    """thread worker function"""
    lock.acquire()
    print('Worker:', num)
    lock.release()

if __name__ == '__main__':
    threads = []
    lock = threading.Lock()
    for i in range(5):
        t = threading.Thread(target=worker, args=(i, lock))
        threads.append(t)
        t.start()
        t.join()

在上面的示例中,我们首先定义了一个函数worker(),该函数通过锁来实现对共享资源的访问。然后,我们在主函数中创建了一个锁对象,并将其作为参数传递给worker()函数。在worker函数中,我们通过acquire和release方法来强制进行锁定和解锁。

2. 避免死锁

死锁是一种在系统中发生的情况,其中线程在无法访问其他线程持有的资源时,无限期地等待另一个线程释放其持有的资源。为了避免死锁,应确保在一次操作期间只锁定一个线程。

以下是避免死锁的示例:

import threading 

def worker_1(lock_1, lock_2):
    """thread worker function"""
    lock_1.acquire()
    print('Worker 1 acquired lock 1')
    lock_2.acquire()
    print('Worker 1 acquired lock 2')
    lock_2.release()
    lock_1.release()

def worker_2(lock_1, lock_2):
    """thread worker function"""
    lock_2.acquire()
    print('Worker 2 acquired lock 2')
    lock_1.acquire()
    print('Worker 2 acquired lock 1')
    lock_1.release()
    lock_2.release()

if __name__ == '__main__':
    lock_1 = threading.Lock()
    lock_2 = threading.Lock()
    t1 = threading.Thread(target=worker_1, args=(lock_1, lock_2))
    t2 = threading.Thread(target=worker_2, args=(lock_1, lock_2))
    t1.start()
    t2.start()
    t1.join()
    t2.join()

在上面的示例中,我们创建了两个线程,它们在处理共享资源时需要使用两个锁。因为这些任务可以相互等待,所以我们通过协调锁的顺序来避免死锁。

3. 使用Thread.join()等待线程

如果在一个线程上调用join()方法,该线程将等待其他线程完成执行后再继续执行。这使得我们可以协调线程的执行,并等待所有线程完成执行后再继续执行其他任务。

以下是使用join()方法的示例:

import threading 
import time

def worker():
    """thread worker function"""
    time.sleep(5)
    print('Worker')

if __name__ == '__main__':
    threads = []
    for i in range(5):
        t = threading.Thread(target=worker)
        threads.append(t)
        t.start()
    for t in threads:
        t.join()
    print('Done')

在上面的示例中,我们创建了五个线程,并使用join()方法将所有线程连接到主线程上,这将等待所有线程执行完毕后才执行print语句。

结论

线程对于同时处理多个任务或进程是非常有用的。在Python中,我们可以使用线程模块来创建和管理线程,并使用一些技巧来避免一些常见的问题。在使用Python线程时,请确保遵循 实践,以确保您的应用程序的安全和性能。