我需要检查至少2万个url,以检查该url是否启动并将一些数据保存在数据库中。
我已经知道如何检查url是否在线以及如何在数据库中保存一些数据。但是,如果没有并发性,检查所有URL将花费很多时间,那么检查数千个URL的最快方法是什么?
我正在遵循本教程:https://realpython.com/python-concurrency/,看来“ CPU绑定多处理版本”是最快的方法,但是我想知道这是最快的方法还是有更好的选择
编辑:
根据回复,我将更新比较多处理和多线程的帖子
示例1: 打印“你好!” 40次
线程
具有8个核心的多处理:
如果使用8个线程,则线程会更好
示例2,这个问题在我的问题中提出:
经过多次测试后,如果使用12个以上线程,则线程传输速度会更快。例如,如果您要测试40个url,并且使用具有40个线程的线程,它将比具有8个内核的多处理速度快50%
感谢您的帮助
答案 0 :(得分:3)
我认为您应该使用pool:pool docs
根据此处的一些结果:mp vs threading SO
我会说总是使用多重处理。也许,如果您希望您的请求花很长时间才能解决,那么线程的上下文切换优势将克服多处理的蛮力
类似
import multiprocessing as mp
urls=['google.com', 'yahoo.com']
with mp.Pool(mp.cpu_count()) as pool:
results=pool.map(fetch_data, urls)
编辑:解决关于一定数量的子流程的注释,我已经展示了如何请求与您的逻辑线程数量相等的流程
答案 1 :(得分:2)
要说多处理永远是最好的选择,那是不正确的,多处理仅对繁重的计算才是最好的!
对于不需要大量计算但仅需执行IN / OUT操作(如数据库记录或远程Webapp api请求)的操作的最佳选择是模块线程。线程处理可能比多处理更快,因为多处理需要序列化数据以将其发送到子进程,而trhead使用相同的内存堆栈。
这种情况下的典型活动是创建输入队列,将任务放入队列并放入任务(您的情况下为URL),并创建多个工作程序以从队列中接收任务:
import threading as thr
from queue import Queue
def work(input_q):
"""the function take task from input_q and print or return with some code changes (if you want)"""
while True:
item = input_q.get()
if item == "STOP":
break
# else do some work here
print("some result")
if __name__ == "__main__":
input_q = Queue()
urls = [...]
threads_number = 8
workers = [thr.Thread(target=work, args=(input_q,),) for i in range(threads_number)]
# start workers here
for w in workers:
w.start
# start delivering tasks to workers
for task in urls:
input_q.put(task)
# "poison pillow" for all workers to stop them:
for i in range(threads_number):
input_q.put("STOP")
# join all workers to main thread here:
for w in workers:
w.join
# show that main thread can continue
print("Job is done.")
答案 2 :(得分:0)
我目前将“多处理与队列一起使用”,它对于我使用的目的来说足够快。
类似于上述Artiom的解决方案,我将进程数设置为80(当前),使用“工人”拉取数据,将其发送到队列中,完成后,根据返回的结果进行处理,具体取决于队列。