Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/361.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 并行读和顺序写?_Python_Python 3.x_Asynchronous_Python Asyncio - Fatal编程技术网

Python 并行读和顺序写?

Python 并行读和顺序写?,python,python-3.x,asynchronous,python-asyncio,Python,Python 3.x,Asynchronous,Python Asyncio,我有以下代码,可以按顺序读取和写入每个id async def main(): while id < 1000: data = await read_async(id) await data.write_async(f'{id}.csv') id += 1 async def main(): 当id

我有以下代码,可以按顺序读取和写入每个
id

async def main():
    while id < 1000:
       data = await read_async(id) 
       await data.write_async(f'{id}.csv')
       id += 1
       
async def main():
当id<1000时:
数据=等待读取异步(id)
等待数据。写入异步(f'{id}.csv')
id+=1
read\u async()
需要几分钟,而
write\u async()
运行不到一分钟。现在我想

  • 并行运行
    read\u async(id)
    。但是,由于内存限制,最多可以并行运行3个调用
  • write\u async
    必须按顺序运行,即
    write\u async(n+1)
    不能在
    write\u async(n)
    之前运行

  • 您可以使用队列和固定数量的任务从主任务进行读取和写入。主任务可以使用一个事件来发现读卡器中有新数据可用,并使用一个共享dict从读卡器中获取数据。例如(未经测试):


    使用单独的结果队列而不是事件队列将不起作用,因为队列是无序的。优先级队列可以解决这个问题,但它仍然会立即返回当前可用的最低id,而编写器需要下一个id才能按顺序处理所有id。

    您好,我很好奇我的回答是否有助于解决这个问题?是的,应该可以。我还没有机会实现它。(现在它仍按顺序运行)。实际上,我的任务是在
    范围(1000)
    中创建一个项目列表,而不是
    id
    ;我现在已经编辑了答案,不要求ID是数字的(其实也没有必要)。
    async def reader(q, id_to_data, data_ready):
        while True:
            id = await q.get()
            data = await read_async(id) 
            id_to_data[id] = data
            data_ready.set()
    
    async def main():
        q = asyncio.Queue()
        for id in range(1000):
            await q.put(id)
    
        id_to_data = {}
        data_ready = asyncio.Event()
        readers = [asyncio.create_task(reader(q, id_to_data, data_ready))
                   for _ in 3]
    
        for id in range(1000):
           while True:
               # wait for the current ID to appear before writing
               if id in id_to_data:
                   data = id_to_data.pop(id)
                   await data.write_async(f'{id}.csv')
                   break
                   # move on to the next ID
               else:
                   # wait for new data and try again
                   await data_ready.wait()
                   data_ready.clear()
    
        for r in readers:
            r.cancel()