你应该看看
asyncio
,它非常简单,可以帮助您更快地完成任务!
阿尔索
multiprocessing.Pool
可以简化代码(以防不想使用asyncio)。
multiprocessing.pool
也有
ThreadPool
如果您喜欢使用线程,则为等效。
关于请求限制,我建议您使用
threading.Semaphore
(或任何其他信号,以防从线程切换)
线程方法:
from multiprocessing.pool import ThreadPool as Pool
from threading import Semaphore
from time import sleep
MAX_RUN_AT_ONCE = 5
NUMBER_OF_THREADS = 10
sm = Semaphore(MAX_RUN_AT_ONCE)
def do_task(number):
with sm:
print(f"run with {number}")
sleep(3)
return number * 2
def main():
p = Pool(NUMBER_OF_THREADS)
results = p.map(do_task, range(10))
print(results)
if __name__ == '__main__':
main()
多处理方法:
from multiprocessing import Pool
from multiprocessing import Semaphore
from time import sleep
MAX_RUN_AT_ONCE = 5
NUMBER_OF_PROCESS = 10
semaphore = None
def initializer(sm):
"""init the semaphore for the child process"""
global semaphore
semaphore = sm
def do_task(number):
with semaphore:
print(f"run with {number}\n")
sleep(3)
return number * 2
def main():
sm = Semaphore(MAX_RUN_AT_ONCE)
p = Pool(NUMBER_OF_PROCESS, initializer=initializer,
initargs=[sm])
results = p.map(do_task, range(10))
print(results)
if __name__ == '__main__':
main()
异步方法:
import asyncio
MAX_RUN_AT_ONCE = 5
sm = asyncio.Semaphore(MAX_RUN_AT_ONCE)
async def do_task(number):
async with sm:
print(f"run with {number}\n")
await asyncio.sleep(3)
return number * 2
async def main():
coros = [do_task(number) for number in range(10)]
finished, _ = await asyncio.wait(coros)
print([fut.result() for fut in finished])
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
用于指挥
http requests
对于asyncio,您应该使用
aiohttp
,也可以使用
requests
具有
loop.run_in_executor
但那就不用了
异步
因为你所有的代码都是请求。
输出:
与0一起运行
使用1运行
与2一起运行
与3一起跑
与4一起跑
(这里有一个暂停du的信号灯和睡眠)
与5一起跑
与6一起跑
用7跑
与8一起跑
用9跑
[0,2,4,6,8,10,12,14,16,18]
你也可以检查
ThreadPoolExecutor