1

我有一個庫,它提供了一個選項,可以在外部作業完成時安排回調。 Future.set_result()使用此回調安全嗎?如果沒有,那麼實現這一目標的正確方法是什麼?未來的文檔說它的方法不是線程安全的,所以我認爲這可能有問題。在來自不同線程的回調中設置asyncio.Future的值

我的目標是使用PyOpenCL中的OpenCL事件作爲asyncio代碼中的等待對象。我在想一個輔助函數是這樣的:

def wrap_opencl_event(event): 
    f = asyncio.Future() 
    event.set_callback(pyopencl.command_execution_status.COMPLETE, lambda x: f.set_result(None)) 
    return f 

,並用它這種方式:

async def do_slow_stuff(): 
    ev1 = pyopencl.enqueue_something() 
    ev2 = pyopencl.enqueue_something_else(wait_for=[ev1]) 
    await wrap_opencl_event(ev2) 
    process_results() 

回答

1

讀一點更徹底看來,未來的價值應該在回調中設置的文件後計劃與事件循環:

def wrap_opencl_event(event): 
    loop = asyncio.get_event_loop() 
    f = loop.create_future() 
    event.set_callback(pyopencl.command_execution_status.COMPLETE, 
         lambda status: loop.call_soon_threadsafe(f.set_result, None)) 
    return f 
0

另一種選擇是使用concurrent.futures和包裹未來

import asyncio.futures, concurrent.futures 
async def func_returning_future(loop): 
    fut = concurrent.futures.Future() 
    # Pass off to your other thread somehow 
    # and return a wrapped future for asyncio 
    return asyncio.futures.wrap_future(fut, loop = loop) 

或者因爲函數是一個異步高清你甚至可以在循環中等待它,與

await asyncio.futures.wrap_future(fut, loop = loop) 
替換最後一行
相關問題