簡體   English   中英

linux:如何同時等待進程和文件?

[英]linux: how to wait for a process and file at the same time?

我正在嘗試在 python 中構建一個事件循環,主要用於教育目的。 我對涉及 asyncio 或類似的解決方案不感興趣,因為我的目標實際上是了解低級 linux API。

對於類文件對象(管道,sockets,...),有 select/poll/epoll 系統調用。 在 python 中,這些都包含在選擇器模塊中。 這是一個可以同時等待多個文件的簡單循環:

file1 = open('/var/run/foo.sock')
file2 = open('/var/run/bar.sock')

with selectors.DefaultSelector() as selector:
    selector.register(file1, selectors.EVENT_READ)
    selector.register(file2, selectors.EVENT_READ)

    while True:
        for key, mask in selector.select():
            if key.fileobj == file1:
                handle_data(file1)
            else:
                handle_data(file2)

對於進程,有等待系統調用。 在 python 中,它被包裝在 subprocess模塊中。 這是等待單個進程終止的代碼:

proc = subprocess.Popen(['/usr/bin/foo'])
proc.wait()
handle_data(proc)

我如何混合這兩者,甚至一次等待多個進程。

selector.select()proc.wait()都會超時,所以我們可以把它變成一個半忙循環:

file1 = open('/var/run/foo.sock')
file2 = open('/var/run/bar.sock')
proc = subprocess.Popen(['/usr/bin/foo'])
timeout = 1

with selectors.DefaultSelector() as selector:
    selector.register(file1, selectors.EVENT_READ)
    selector.register(file2, selectors.EVENT_READ)

    while True:
        for key, mask in selector.select(timeout):
            if key.fileobj == file1:
                handle_data(file1)
            else:
                handle_data(file2)

        if proc:
            try:
                proc.wait(timeout)
                handle_data(proc)
                proc = None
            except TimeoutExpired:
                pass

我想一定有更好的方法。 這通常是如何完成的?

在查看python的asyncio中child watchers的不同實現時,找到了相關資料:

  • 您可以在單獨的線程中調用os.waitpid()並在完成后寫入 pipe。 pipe 的另一端可以添加到 select 循環中。 這種方法似乎是最常見的。
  • 您可以在收到SIGCHLD時寫入 pipe,然后再次將該 pipe 的另一端添加到 select 循環。 然后你可以調用process.poll()來檢查哪個進程在 O(n) 時間內終止了。
  • open_pidfd()正是我要找的。 它是最干凈的解決方案,但僅適用於 Linux >= 5.3。 如果您不必關心可移植性,這可能是通往 go 的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM