面试题答案
一键面试multiprocessing
基本使用方法
- 创建进程:
- 可以通过继承
multiprocessing.Process
类,并重写run
方法来创建进程。
import multiprocessing class MyProcess(multiprocessing.Process): def run(self): print(f"子进程 {self.name} 运行中") if __name__ == '__main__': p = MyProcess() p.start() p.join()
- 也可以直接使用
multiprocessing.Process
类,传入要执行的函数。
import multiprocessing def worker(): print("子进程运行中") if __name__ == '__main__': p = multiprocessing.Process(target=worker) p.start() p.join()
- 可以通过继承
- 传递参数:在使用
Process
类传入函数时,可以通过args
或kwargs
传递参数。import multiprocessing def worker(num): print(f"子进程运行,参数为 {num}") if __name__ == '__main__': p = multiprocessing.Process(target=worker, args=(10,)) p.start() p.join()
- 进程间通信:
- 队列(Queue):用于在进程间传递数据。
import multiprocessing def producer(queue): for i in range(5): queue.put(i) def consumer(queue): while True: item = queue.get() if item is None: break print(f"消费: {item}") if __name__ == '__main__': q = multiprocessing.Queue() p1 = multiprocessing.Process(target=producer, args=(q,)) p2 = multiprocessing.Process(target=consumer, args=(q,)) p1.start() p2.start() p1.join() q.put(None) p2.join()
- 管道(Pipe):用于创建双向或单向的通信通道。
import multiprocessing def sender(conn): conn.send('Hello, receiver!') conn.close() def receiver(conn): msg = conn.recv() print(f"接收: {msg}") conn.close() if __name__ == '__main__': parent_conn, child_conn = multiprocessing.Pipe() p1 = multiprocessing.Process(target=sender, args=(child_conn,)) p2 = multiprocessing.Process(target=receiver, args=(parent_conn,)) p1.start() p2.start() p1.join() p2.join()
与线程在数据共享和资源利用方面的不同
- 数据共享:
- 线程:线程间共享全局变量,多个线程可以直接访问和修改相同的变量,这在提高数据访问效率的同时,容易引发资源竞争问题,需要使用锁(
Lock
)等机制来保证数据一致性。 - 多进程:每个进程有自己独立的内存空间,默认情况下进程间数据不共享。如果需要共享数据,需要使用
multiprocessing
提供的Value
、Array
等共享内存对象,或者通过进程间通信(如队列、管道)来传递数据,相比线程数据共享的复杂性较低,但操作相对繁琐。
- 线程:线程间共享全局变量,多个线程可以直接访问和修改相同的变量,这在提高数据访问效率的同时,容易引发资源竞争问题,需要使用锁(
- 资源利用:
- 线程:所有线程共享进程的资源,如内存空间、文件描述符等,创建和销毁线程的开销相对较小。但是,由于全局解释器锁(GIL)的存在,在CPU密集型任务中,Python多线程无法充分利用多核CPU的优势,同一时间只有一个线程能执行Python字节码。
- 多进程:每个进程拥有独立的资源,创建和销毁进程的开销相对较大。但是,多进程可以充分利用多核CPU的优势,适合CPU密集型任务,每个进程可以在不同的CPU核心上并行执行,提高整体的计算效率。