您的位置:

Python多线程并发编程示例

Python是一门高级编程语言,其强大的多线程并发编程功能使其成为开发人员喜爱的语言之一。多线程在Python中可以使用threading模块来实现。本文将介绍Python多线程并发编程示例,以帮助读者在实践中掌握该技术。

一、创建线程

线程是轻量级的执行单元,它是CPU调度的最小单位,相比进程更加轻便。Python中的线程使用threading模块来创建。要创建线程,需要实例化一个Thread对象并指定目标函数和参数。

import threading

def worker(num):
    """线程要执行的任务"""
    print(f"Worker {num} 执行中...\n")

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

for t in threads:
    t.join()  # 等待所有线程完成

以上代码创建了5个线程,每个线程执行一个名为worker的函数,并传入一个参数。在运行前,我们将这些线程全部放入了一个列表threads中。最后,我们使用join函数让主线程等待所有工作线程的完成。

二、线程同步

当多个线程同时访问同一个共享资源时,就会发生线程安全问题。Python提供了一些同步机制来解决这些问题。

1. Lock锁

Lock是一种最简单的同步机制,它提供了一种独占式的访问机制,即同一时刻只允许一个线程访问共享资源。

import threading

class Counter:
    def __init__(self):
        self._value = 0
        self._lock = threading.Lock()

    def increment(self):
        """线程安全的计数器"""
        with self._lock:
            self._value += 1
            print(f"当前值为: {self._value}\n")

counter = Counter()

threads = []
for i in range(5):
    t = threading.Thread(target=counter.increment)
    threads.append(t)
    t.start()

for t in threads:
    t.join()  # 等待所有线程完成

以上代码创建了一个Counter类,它有一个increment函数来执行计数器的实际操作。在increment函数的代码块中,使用了with语句来获得锁并保证线程安全。

2. Condition条件变量

当多个线程需要等待某个共享资源时,使用Condition是一种比较常见的同步机制。它提供了一个wait方法来挂起当前线程,并且可以通过notify或notifyAll方法来恢复线程。

import threading

class Server:
    def __init__(self):
        self._data = None
        self._cond = threading.Condition()

    def produce(self, data):
        """向服务端写入数据"""
        with self._cond:
            self._data = data
            print(f"生产者写入数据: {self._data}\n")
            self._cond.notify()
    
    def consume(self):
        """从服务端读取数据"""
        with self._cond:
            while self._data is None:
                self._cond.wait()
            data = self._data
            self._data = None
            print(f"消费者读取数据: {data}\n")

server = Server()

threads = []
t1 = threading.Thread(target=server.consume)
t2 = threading.Thread(target=server.produce, args=('Hello World!',))
threads.extend([t1, t2])
for t in threads:
    t.start()

for t in threads:
    t.join()  # 等待所有线程完成

以上代码创建了一个Server类,它有一个produce函数用于向服务端写入数据,另一个consume函数用于从服务端读取数据。在consume函数内部,给定一个while循环来等待数据的到来,在produce函数内部使用了notify方法来通知消费者。

三、GIL全局解释器锁

Python解释器中有一个GIL全局解释器锁,它限制了Python线程的并行执行。GIL是必要的,因为CPython的内存管理是不可重入的,意味着在任何时刻只有一个线程可以执行Python代码。使用GIL可以确保C代码作为共享数据的访问协调器而运行。

但是,GIL也会带来一些负面影响。当我们创建多个线程来处理计算密集型任务时,GIL会使得它们不能同时运行,从而导致效率下降。因此,在这种情况下,应该使用多进程并发编程技术来获得最佳性能。

总结

本文介绍了Python多线程并发编程的示例,从创建线程和线程同步机制到GIL全局解释器锁的介绍,我们希望能够帮助读者更好地掌握Python多线程并发编程技术。