將一些代碼轉換爲使用asyncio,我想盡快地控制asyncio.BaseEventLoop
。這意味着要避免阻止等待。asyncio如何安排文件系統統計操作?
沒有asyncio我會用os.stat()
或pathlib.Path.stat()
來獲得例如。文件大小。有沒有一種方法可以有效地用asyncio做到這一點?
我可以直接打包stat()
電話,因此它是類似於described here的未來嗎?
將一些代碼轉換爲使用asyncio,我想盡快地控制asyncio.BaseEventLoop
。這意味着要避免阻止等待。asyncio如何安排文件系統統計操作?
沒有asyncio我會用os.stat()
或pathlib.Path.stat()
來獲得例如。文件大小。有沒有一種方法可以有效地用asyncio做到這一點?
我可以直接打包stat()
電話,因此它是類似於described here的未來嗎?
os.stat()
轉化爲一個系統調用stat
:
$ strace python3 -c 'import os; os.stat("/")'
[...]
stat("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
[...]
被攔截,而且也沒有辦法讓一個無阻塞stat
系統調用。
asyncio
提供無阻塞通過使用非阻斷系統調用,這已經存在的I/O(參見man fcntl
,以其O_NONBLOCK
標誌,或ioctl
),所以asyncio
不使系統調用異步的,它暴露在已經異步系統調用一個不錯的方法。
仍然可以使用漂亮的ThreadPoolExecutor抽象來使用線程池並行阻止stat
調用。
但是你可以先考慮一些其他參數:
strace -T
,stat
快:stat("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 <0.000007>
,可能快於啓動和同步線程。stat
可能是在很多情況下IO的約束,因此,使用多個CPU不會幫助但是你的stat
的使用線程池的可能性也很大,就像你打到分佈式文件系統一樣。
您也可以查看functools.lru_cache
:如果您在同一個文件或目錄中執行多個stat
,並且您確定它沒有更改,緩存結果可避免系統調用。
總之,「保持簡單」,「os.stat」是是獲取文件大小的有效方式。
你的意思是:你想要一個非阻塞的'os.stat()',這樣其他協程可以在其中運行嗎? –
@Julien:是的,我認爲是的;-)爲了讓主代碼並行運行,我將被迫使用線程而不是asyncio,對嗎? – cfi