Python全局锁(GIL)是一种常见的内置锁,它限制了同一时间只能有一个线程在CPU中运行Python代码。这个特性使得Python多线程不能像其他语言一样实现真正的并行处理。但是在特定场景中,可以有效地运用多线程或多进程来提升程序性能。
为了合理运用多线程或多进程,我们可以考虑以下几个方面:
- 使用多个进程。多个进程可以避开Python GIL的限制,同时使用IPC(进程间通信)机制来共享资源。Python的标准库提供了
multiprocessing
模块,其中的Process
类可以创建子进程。
示例1:使用multiprocessing
模块创建子进程并使用队列实现进程间通信。
import time
import multiprocessing
def worker(q):
while True:
if not q.empty():
item = q.get()
print(f'Worker got {item}')
time.sleep(1)
else:
break
if __name__ == '__main__':
q = multiprocessing.Queue()
process1 = multiprocessing.Process(target=worker, args=(q,))
process2 = multiprocessing.Process(target=worker, args=(q,))
process1.start()
process2.start()
for i in range(10):
q.put(i)
process1.join()
process2.join()
- 使用线程池。Python的标准库提供了
concurrent.futures
模块,其中的ThreadPoolExecutor
类和ProcessPoolExecutor
类可以分别创建线程池和进程池,以实现多线程或多进程处理。
示例2:使用ThreadPoolExecutor
模块创建线程池并同时执行多个任务。
import concurrent.futures
def worker(num):
time.sleep(num)
print(f'Worker {num} finished')
return num
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
results = [executor.submit(worker, i) for i in range(3, 8)]
for future in concurrent.futures.as_completed(results):
print(f'Result of {future.result()}')
在使用多线程或多进程时,注意以下几点:
- 避免共享变量:共享变量容易造成竞态条件(race condition),可使用
multiprocessing
的Manager
类和multiprocessing
、concurrent.futures
的Queue
类等实现进程(线程)间通信。 - 尽量选择CPU密集型任务:由于全局锁的存在,多线程不适合IO密集型任务,而多进程(线程)可使用IO密集型任务,同时它们特别适合CPU密集型任务。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python全局锁中如何合理运用多线程(多进程) - Python技术站