python3 sleep 并发_Python3 并发 | concurrent.futures

本文介绍了如何使用Python3的concurrent.futures模块实现并发任务,包括ThreadPoolExecutor的使用,如并行查询任务、管理任务的执行以及通过队列实现并发。示例代码展示了多种并发执行任务的方法,如map、submit和wait等。
摘要由CSDN通过智能技术生成

# -*- coding: utf-8 -*-

from concurrent.futures import ThreadPoolExecutor, wait, as_completed, ALL_COMPLETED

import logging

import random

import queue

import time

logger = logging.getLogger()

logger.setLevel(logging.INFO)

ch = logging.StreamHandler()

ch.setLevel(logging.INFO)

formatter = logging.Formatter('%(asctime)s - [line:%(lineno)d] %(levelname)s - %(message)s')

ch.setFormatter(formatter)

logger.addHandler(ch)

fh = logging.FileHandler(r'spider.log', encoding='utf-8')

fh.setFormatter(formatter)

logger.addHandler(fh)

class TPE(ThreadPoolExecutor):

"""

并行任务

# 官方文档 https://docs.python.org/zh-cn/3.7/library/concurrent.futures.html

"""

def __init__(self, max_workers=None, thread_name_prefix=''):

super().__init__(max_workers, thread_name_prefix)

def run(self):

self.num_list = [i for i in range(0, 100)]

num = self.submit(self.manage_task)

# 设置任务列表大小

group_size = 10

while self.num_list:

# # # 方式一

# 每次 10 个任务

result = self.map(self.query_task, self.num_list[:group_size])

for result in result:

logger.info(f"result | {result}")

# # # 方式二

# 重新定义最大线程数 5

# with ThreadPoolExecutor(max_workers=5) as executor:

# # 列表模式

# futures = [executor.submit(self.query_task, f"{n}") for n in self.num_list[:group_size]]

# # 等待 futures 中的任务全部结束

# wait(futures, return_when=ALL_COMPLETED)

# for future in as_completed(futures):

# logger.info(future.result())

# # 字典模式

# futures = {executor.submit(self.query_task, n): n for n in self.num_list[:group_size]}

# for future in as_completed(futures):

# infos = futures[future]

# data = future.result()

# logger.info(data)

# # # 方式三

# 既然都继承了直接 submit

# futures = [self.submit(self.query_task, f"{n}") for n in self.num_list[:group_size]]

# # 等待 futures 中的任务全部结束

# wait(futures, return_when=ALL_COMPLETED)

# for future in as_completed(futures):

# logger.info(future.result())

# 重新赋值,切割列表

self.num_list = self.num_list[group_size:]

logger.info(self.num_list)

time.sleep(1)

def query_task(self, num):

"""

任务

:param num:

:return:

"""

logger.info(f"query task | {num}")

time.sleep(1)

result = {}

result['succeed'] = True

result['num'] = num

return result

def manage_task(self):

while True:

if not self.num_list:

return True

n = random.randint(-1, 999)

self.num_list.append(n)

logger.info(f"add new task | {n}")

time.sleep(1.5)

if __name__ == '__main__':

# 设置最大并发数

t = TPE(max_workers=10)

t.run()

使用队列

# -*- coding: utf-8 -*-

from concurrent.futures import ThreadPoolExecutor

import logging

import random

import queue

import time

logger = logging.getLogger()

logger.setLevel(logging.INFO)

ch = logging.StreamHandler()

ch.setLevel(logging.INFO)

formatter = logging.Formatter('%(asctime)s - [line:%(lineno)d] %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')

ch.setFormatter(formatter)

logger.addHandler(ch)

fh = logging.FileHandler(r'queue.log', encoding='utf-8')

fh.setFormatter(formatter)

logger.addHandler(fh)

class TPE(ThreadPoolExecutor):

def __init__(self, max_workers=None, thread_name_prefix=''):

super().__init__(max_workers, thread_name_prefix)

self.proxy_queue = queue.Queue(maxsize=0)

self.domain_list = []

def run(self):

# 开始程序, 添加 10 个值

[self.proxy_queue.put(random.randint(1, 99)) for i in range(10)]

self.submit(self.manage_queue)

time.sleep(0.1)

self.submit(self.talk)

def talk(self):

while not self.proxy_queue.empty():

# 取值

for i in range(3):

logger.info(f"获取值:{self.proxy_queue.get()} | 队列: {self.proxy_queue.qsize()}")

print()

time.sleep(2.1)

def manage_queue(self):

while True:

if self.proxy_queue.empty():

return True

# 队列添加值

n = random.randint(1, 99)

self.proxy_queue.put(n)

logger.info(f"添加值:{n}")

time.sleep(0.9)

if __name__ == '__main__':

t = TPE(max_workers=5)

t.run()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值