Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x 如何使用Python';使用异步IO队列来模拟线程?_Python 3.x_Multithreading_Websocket_Concurrency_Python Asyncio - Fatal编程技术网

Python 3.x 如何使用Python';使用异步IO队列来模拟线程?

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

我试图通过使用asyncio.Queue来模拟线程中的处理。然而,我正在努力将线程处理模拟部分转换为异步循环

因此,我的脚本的作用很简单:1)通过websocket接收处理请求,2)将请求分配给请求队列(模拟线程),3)运行处理队列,将响应放入一个共享响应队列,然后4)websocket从共享队列中逐个取出响应并将其发送到服务器

我的代码的简化版本:

#为要模拟的线程数初始化空处理队列
正在处理范围内的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“我不能接受”是什么意思?您是否遇到异常,它是否以某种方式不起作用,您的代码是什么样子,您采取了什么步骤来调试它?无需担心。已设法用另一条语句阻止。感谢您的帮助。