python 多进程和多线程使用详解

  

Python 多进程和多线程使用详解

Python 作为一门高级语言,在并发编程方面拥有很好的支持。在多进程和多线程方面,Python 同样提供了丰富的标准库支持。在本文中,我们将详细讲解并发编程中的多进程和多线程的使用。

多进程

基本概念

多进程是指在一个程序中同时运行多个并发执行的任务,每个任务拥有独立的进程空间。在 Python 中,我们可以通过创建多个进程来实现多进程,并且 Python 提供了 multiprocessing 模块用于实现多进程。

示例一:快速创建多进程

在 Python 中,使用 Process 类可以创建一个新的进程。下面的代码展示了如何快速创建多个进程:

import os
from multiprocessing import Process

def func(name):
    print('process %s start' % name)
    print('parent process id:', os.getppid())
    print('process id:', os.getpid())
    print('process %s end' % name)

if __name__ == '__main__':
    for i in range(5):
        p = Process(target=func, args=(str(i),))
        p.start()
        p.join()
    print('main process end')

这里定义了一个 func 函数,参数为进程的名称。使用 Process 类创建进程时,需要指定参数 targetargstarget 参数用于指定进程要执行的函数,args 参数是传入该函数的参数组成的元组。

在创建多个进程后,可以使用 join() 方法使主进程等待所有进程完成。这样可以确保进程间的执行顺序,避免出现混乱的输出结果。

示例二:多进程共享变量

在多进程编程中,可以使用 ValueArray 类来共享变量。它们分别是通过共享一个 ctypes 类型的数据块实现的。

下面的代码展示了如何使用 Value 共享一个数值:

from multiprocessing import Process, Value

def f(n):
    for i in range(10):
        n.value += 1

if __name__ == '__main__':
    num = Value('i', 0)
    ps = []
    for i in range(5):
        p = Process(target=f, args=(num,))
        p.start()
        ps.append(p)
    for p in ps:
        p.join()
    print(num.value)

这里定义了一个 f 函数,在该函数中,将共享变量 n 的值增加 10 次。在主函数中,我们使用 Value 创建一个数值类型的共享变量,然后创建多个进程并启动它们,每个进程都执行 f 函数,修改该共享变量的值。

最后,我们使用 join() 方法等待所有进程执行结束,并输出共享变量的值。

多线程

基本概念

多线程是指在一个进程中同时运行多个并发执行的任务,每个任务拥有独立的线程空间。在 Python 中,我们可以通过创建多个线程来实现多线程,并且 Python 提供了 threading 模块用于实现多线程。

示例三:快速创建多线程

在 Python 中,使用 Thread 类可以创建一个新的线程。下面的代码展示了如何快速创建多个线程:

import threading

def func(name):
    print('thread %s start' % name)
    print('thread %s end' % name)

if __name__ == '__main__':
    ts = []
    for i in range(5):
        t = threading.Thread(target=func, args=(str(i),))
        t.start()
        ts.append(t)
    for t in ts:
        t.join()
    print('main thread end')

这里定义了一个 func 函数,参数为线程的名称。使用 Thread 类创建线程时,需要指定参数 targetargstarget 参数用于指定线程要执行的函数,args 参数是传入该函数的参数组成的元组。

在创建多个线程后,可以使用 join() 方法使主线程等待所有线程完成。这样可以确保线程间的执行顺序,避免出现混乱的输出结果。

示例四:多线程共享变量

在多线程编程中,可以使用 Lock 类来同步多个线程对共享变量的访问,避免出现竞争状态。下面的代码展示了如何使用 Lock 同步多个线程对共享变量的访问:

import threading

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

    def increment(self):
        with self._lock:
            self._value += 1

    @property
    def value(self):
        with self._lock:
            return self._value

def worker(counter):
    for i in range(10000):
        counter.increment()

if __name__ == '__main__':
    counter = Counter()
    ts = []
    for i in range(5):
        t = threading.Thread(target=worker, args=(counter,))
        t.start()
        ts.append(t)
    for t in ts:
        t.join()
    print(counter.value)

这里定义了一个 Counter 类,用于封装共享变量 valuelock 对象。在 increment 方法中,使用 with 语句实现线程安全的自增操作;在 value 属性中,也使用 with 语句实现线程安全的读取操作。

在主函数中,我们创建一个 Counter 对象,并启动多个线程,每个线程都执行 worker 函数,调用 increment 方法修改共享变量的值。

最后,我们使用 join() 方法等待所有线程执行结束,并输出共享变量的值。

总结

本文详细讲解了 Python 中多进程和多线程的使用方法和注意事项,包括快速创建多进程/多线程、多进程/多线程共享变量等内容。使用多进程和多线程可以提高程序的并发性和效率,是 Python 并发编程中的核心知识点。

相关文章