Python 3.x 如何使用Python';使用异步IO队列来模拟线程?
我试图通过使用asyncio.Queue来模拟线程中的处理。然而,我正在努力将线程处理模拟部分转换为异步循环 因此,我的脚本的作用很简单:1)通过websocket接收处理请求,2)将请求分配给请求队列(模拟线程),3)运行处理队列,将响应放入一个共享响应队列,然后4)websocket从共享队列中逐个取出响应并将其发送到服务器 我的代码的简化版本:Python 3.x 如何使用Python';使用异步IO队列来模拟线程?,python-3.x,multithreading,websocket,concurrency,python-asyncio,Python 3.x,Multithreading,Websocket,Concurrency,Python Asyncio,我试图通过使用asyncio.Queue来模拟线程中的处理。然而,我正在努力将线程处理模拟部分转换为异步循环 因此,我的脚本的作用很简单:1)通过websocket接收处理请求,2)将请求分配给请求队列(模拟线程),3)运行处理队列,将响应放入一个共享响应队列,然后4)websocket从共享队列中逐个取出响应并将其发送到服务器 我的代码的简化版本: #为要模拟的线程数初始化空处理队列 正在处理范围内的i(n个队列)的\u队列=[asyncio.Queue() #初始化共享响应队列 响应_q=a
#为要模拟的线程数初始化空处理队列
正在处理范围内的i(n个队列)的\u队列=[asyncio.Queue()
#初始化共享响应队列
响应_q=asyncio.Queue()
#设置websocket上下文管理器
与websocket异步。将(f“ws://{host}:{port}”)连接为websocket:
尽管如此:
#读取传入请求
message=wait websocket.recv()
#解析mssg->获取请求数据以及在哪个线程/队列上处理数据
请求数据,队列号=解析消息(消息)
#将请求数据放入请求队列(模拟线程)
等待处理队列[队列编号].put(请求数据)
#这就是我认为异步中断的地方(我需要帮助)
#在每个模拟处理线程中进行处理
对于处理队列中的proc_q:
如果不是proc_q.empty():
request_data=wait proc_q.get()
#处理
响应=过程数据(请求数据)
#将响应添加到响应队列
等待响应\u q.put(响应)
#将响应发送回服务器
如果没有响应,则为空()
response\u data=response\u q.get()
等待websocket.send(响应数据)
根据脚本的输出,我推断1)我似乎异步接收请求并发送响应;2)队列中的处理不会异步进行。如果我错了,请纠正我
我正在读有关asyncio中的create_task()
。也许这可以解决我的问题
我对任何解决方案都持开放态度(即使是黑客)
另外,我只会使用线程库中的线程,但我需要用于websockets库的asyncio
p.p.S.我的想法的线程版本
class ProcessingImitationThread(threading.Thread):
def __init__(self, thread_id, request_q, response_q):
threading.Thread.__init__(self)
self.thread_id = thread_id
self.request_q = request_q
self.response_q = response_q
def run(self):
while True:
try:
(x, request_id) = self.request_q.get()
except Empty:
time.sleep(0.2)
else:
if x == -1:
# EXIT CONDITION
break
else:
sleep_time_for_x = count_imitation(x, state)
time.sleep(sleep_time_for_x)
self.response_q.put(request_id)
print(f"request {request_id} executed")
# Set up
processing_qs = [queue.Queue() for i in range(n_processes_simulated)]
response_q = queue.Queue()
processing_thread_handlers = []
for i in n_processes_simulated:
# create thread
t = ProcessingImitationThread(i, processing_qs[i], response_q)
processing_thread_handlers.append(t)
# Main loop
while True:
# receive requests and assign to requested queue (so that thread picks up)
if new_request:
requested_process, x, request_id = parse(new_request)
processing_qs[requested_process].put((x, request_id))
...
# if there are any new responses, sent them out to the server
if response_q.q_size() > 0:
request_id = response_q.get()
# Networking: send to server
...
# Close down
...
编辑:修复小的打字错误。您需要的
创建任务
的直觉是正确的,因为创建任务
是与线程最接近的异步等价物。启动
:它创建一个与您现在所做的事情并行运行的任务(在异步意义上)
您需要单独的协同路由来消耗并行运行的各个队列;类似于这样:
async def main():
processing_qs = [asyncio.Queue() for i in range(n_queues)]
response_q = asyncio.Queue()
async with websockets.connect(f"ws://{host}:{port}") as websocket:
processing_tasks = [
asyncio.create_task(processing(processing_q, response_q))
for processing_q in processing_qs
]
response_task = asyncio.create_task(
send_responses(websocket, response_q))
while True:
message = await websocket.recv()
requested_process, x, request_id = parse(message)
await processing_qs[requested_process].put((x, request_id))
async def processing(processing_q, response_q):
while True:
x, request_id = await processing_q.get()
... create response ...
await response_q.put(response)
async def send_responses(websocket, response_q):
while True:
msg = await response_q.get()
await websocket.send(msg)
您需要
create_task
的直觉是正确的,因为create_task
是与线程最接近的异步等价物。start
:它创建了一个并行运行的任务(在异步意义上)无论你现在做什么。但是从你的伪代码很难判断你想做什么。你真的需要处理队列
成为队列列表吗?应该如何处理.queues.put(x)
即使是工作,因为它是一个列表?你能编写一个多线程版本的伪代码,这样我们就可以了解你首先想要的是什么吗?修复了代码,它应该是:处理队列[queue\u no].put(request\u info)。所有请求都包括关于哪个“线程”的信息应该对它们进行处理。是否可以显示使用线程的等效伪代码?完成!为线程版本添加了伪代码。谢谢。这似乎有帮助。但是,我在websocket方面遇到了一些问题。在像您一样使用websocket两次调用create_任务后,我无法恢复suggested@RytisJonynas“我不能接受”是什么意思?您是否遇到异常,它是否以某种方式不起作用,您的代码是什么样子,您采取了什么步骤来调试它?无需担心。已设法用另一条语句阻止。感谢您的帮助。