手把手带你了解Python多进程、多线程
本文将会介绍Python多进程、多线程的相关知识和使用方法。首先会了解它们的概念和区别,然后会分别介绍它们的具体实现方法,并提供两个示例来帮助理解。
什么是多进程和多线程
多进程和多线程都是为了提高计算机运行效率而产生的技术。
多进程是指同时运行多个独立的进程在不同的CPU中或同一个CPU的不同内核中执行。每个进程都有自己的运行空间和堆栈,它们互不干扰,也不共享变量,进程之间只能通过进程间通信(IPC)来交换数据。每个进程都有自己的独立地址空间,因此每个进程对于同一变量会有自己的一份拷贝,互不影响。
多线程是指在同一进程中同时运行多个线程的技术。每个线程都共享同一进程的运行空间和堆栈,线程之间可以共享变量,也可以通过互斥锁、信号量等同步机制来协调访问共享变量。由于线程之间共享进程的地址空间,因此对于同一变量的访问不同线程之间是共享的。
Python实现多进程和多线程
Python标准库multiprocessing
和threading
提供了Python实现多进程和多线程的相关模块。
多进程
使用multiprocessing
模块实现多进程,需要先导入multiprocessing
模块,然后定义一个函数作为进程的执行体,最后创建进程对象并启动进程,示例如下:
import multiprocessing
import time
def worker(num):
print(f"Starting worker {num}...")
time.sleep(3)
print(f"Worker {num} finished.")
if __name__ == '__main__':
process1 = multiprocessing.Process(target=worker, args=(1,))
process2 = multiprocessing.Process(target=worker, args=(2,))
process1.start()
process2.start()
process1.join()
process2.join()
上述代码中,首先定义了一个worker
函数作为进程的执行体,该函数有一个参数num
,表示进程编号。然后创建了两个进程对象process1
和process2
,分别绑定到worker
函数,并传入不同的参数1和2,即进程1和进程2的编号。最后启动两个进程并等待两个进程的结束。
多线程
使用threading
模块实现多线程,需要先导入threading
模块,然后定义一个函数作为线程的执行体,最后创建线程对象并启动线程,示例如下:
import threading
import time
def worker(num):
print(f"Starting worker {num}...")
time.sleep(3)
print(f"Worker {num} finished.")
if __name__ == '__main__':
thread1 = threading.Thread(target=worker, args=(1,))
thread2 = threading.Thread(target=worker, args=(2,))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
上述代码中,首先定义了一个worker
函数作为线程的执行体,该函数有一个参数num
,表示线程编号。然后创建了两个线程对象thread1
和thread2
,分别绑定到worker
函数,并传入不同的参数1和2,即线程1和线程2的编号。最后启动两个线程并等待两个线程的结束。
示例
使用多进程进行计算密集型任务
下面给出一个使用多进程进行计算密集型任务的例子,计算从1加到1000000的结果,可以将任务分成10个子任务分别在不同的进程中运行,最后汇总得到结果。代码如下:
import multiprocessing
def worker(start, end, result):
sum = 0
for i in range(start, end + 1):
sum += i
result.put(sum)
if __name__ == '__main__':
result = multiprocessing.Queue()
jobs = []
for i in range(1, 11):
start = (i - 1) * 100000 + 1
end = i * 100000
p = multiprocessing.Process(target=worker, args=(start, end, result))
jobs.append(p)
p.start()
for job in jobs:
job.join()
total = 0
while not result.empty():
total += result.get()
print(f"Total: {total}")
上述代码中,首先定义了一个worker
函数,它的参数start
和end
表示计算范围的起始和结束值,result
表示放置每个子任务结果的队列。在主程序中,创建10个进程分别计算1-100000,100001-200000,…,900001-1000000的结果,最后从队列中获取每个进程的结果并汇总得到总结果。
使用多线程进行IO密集型任务
下面给出一个使用多线程进行IO密集型任务的例子,模拟爬取3个网站的内容,可以将每个网站分别放到不同的线程中爬取,在执行过程中可以看到不同的线程交替运行。代码如下:
import threading
import requests
import time
def crawler(url):
print(f"Start crawling {url}...")
response = requests.get(url)
print(f"Crawling {url} finished.")
return response
if __name__ == '__main__':
urls = ["https://www.baidu.com", "https://www.sina.com", "https://www.qq.com"]
threads = []
for url in urls:
t = threading.Thread(target=crawler, args=(url,))
threads.append(t)
t.start()
for t in threads:
t.join()
上述代码中,首先定义了一个crawler
函数,它的参数url
表示需要爬取的网站地址。在主程序中,创建3个线程分别爬取三个网站,通过观察输出可以看到不同的线程交替运行,以此提高程序的效率。
总结
本文介绍了Python多进程、多线程的概念和实现方法,并通过示例演示了使用多进程和多线程进行计算密集型和IO密集型任务的方法。在使用多进程和多线程的过程中,需要注意多进程之间的内存共享访问和多线程之间的资源互斥访问,尤其注意进程池和线程池在平衡性、性能、控制进程或线程数量等方面的特点和不同。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:手把手带你了解python多进程,多线程 - Python技术站