多进程&多线程

0 阅读2分钟

多进程编程

基本概念

多进程(multiprocessing)是指同时运行多个进程的程序设计方式。在Unix/Linux系统中,可以使用fork()系统调用创建子进程。

创建进程的三种方式

1. 使用os.fork()(仅Unix/Linux/macOS)

import os

pid = os.fork()
if pid == 0:
    print('子进程')
else:
    print('父进程')

2. 使用multiprocessing.Process

from multiprocessing import Process
import os

def run_proc(name):
    print(f'子进程 {name} ({os.getpid()})')

if __name__ == '__main__':
    p = Process(target=run_proc, args=('test',))
    p.start()
    p.join()  # 等待子进程结束

3. 使用进程池Pool

from multiprocessing import Pool
import os, time

def long_time_task(name):
    print(f'任务 {name} ({os.getpid()})')
    time.sleep(2)

if __name__ == '__main__':
    p = Pool(4)  # 最多同时执行4个进程
    for i in range(5):
        p.apply_async(long_time_task, args=(i,))
    p.close()
    p.join()

进程间通信

使用Queue实现进程间数据交换:

from multiprocessing import Process, Queue
import os, time

def write(q):
    for value in ['A', 'B', 'C']:
        q.put(value)
        time.sleep(1)

def read(q):
    while True:
        value = q.get(True)
        print(f'获取: {value}')

if __name__ == '__main__':
    q = Queue()
    pw = Process(target=write, args=(q,))
    pr = Process(target=read, args=(q,))
    pw.start()
    pr.start()
    pw.join()
    pr.terminate()

多线程编程

基本使用

import threading
import time

def loop():
    print(f'线程 {threading.current_thread().name} 运行中')
    for i in range(5):
        print(f'线程 {threading.current_thread().name} >>> {i}')
        time.sleep(1)

t = threading.Thread(target=loop, name='LoopThread')
t.start()
t.join()

线程安全与锁机制

多线程共享变量可能导致数据混乱,需要使用锁来保证线程安全:

import threading

balance = 0
lock = threading.Lock()

def change_it(n):
    global balance
    balance = balance + n
    balance = balance - n

def run_thread(n):
    for i in range(100000):
        lock.acquire()  # 获取锁
        try:
            change_it(n)
        finally:
            lock.release()  # 释放锁

ThreadLocal:线程局部变量

import threading

local_school = threading.local()

def process_student():
    std = local_school.student
    print(f'Hello, {std} (in {threading.current_thread().name})')

def process_thread(name):
    local_school.student = name
    process_student()

进程 vs. 线程比较

优缺点对比

  • 多进程 优点:稳定性高,子进程崩溃不影响主进程 缺点:创建开销大,占用资源多
  • 多线程 优点:创建开销小,共享内存方便 缺点:一个线程崩溃可能导致整个进程崩溃

适用场景

  • 计算密集型任务:适合用多进程,最好用C语言编写
  • IO密集型任务:适合用多线程,Python是良好选择

Python的GIL限制

Python的全局解释器锁(GIL)限制了多线程无法真正利用多核CPU。要充分利用多核,应使用多进程或C扩展。

分布式进程

使用multiprocessing.managers模块可以实现分布式多进程:

服务端(task_master.py)

from multiprocessing.managers import BaseManager
import queue

task_queue = queue.Queue()
result_queue = queue.Queue()

class QueueManager(BaseManager): pass

QueueManager.register('get_task_queue', callable=lambda: task_queue)
QueueManager.register('get_result_queue', callable=lambda: result_queue)

manager = QueueManager(address=('', 5000), authkey=b'abc')
manager.start()

客户端(task_worker.py)

class QueueManager(BaseManager): pass

QueueManager.register('get_task_queue')
QueueManager.register('get_result_queue')

m = QueueManager(address=('127.0.0.1', 5000), authkey=b'abc')
m.connect()
task = m.get_task_queue()
result = m.get_result_queue()

总结

  • 多进程适合CPU密集型任务,稳定性更好
  • 多线程适合IO密集型任务,创建开销小
  • Python有GIL限制,多线程无法利用多核
  • 分布式进程可以将任务分布到多台机器执行
  • 根据具体需求选择合适的并发模型