簡體   English   中英

如何在Python 3中實現POSIX文件描述符?

[英]How can I implement a POSIX file descriptor in Python 3?

我想寫一個可以表現為真正的文件描述符的類。 它的.fileno()方法應返回一個文件描述符,它提供POSIX系統所需的所有服務。

這是我第一次涉足POSIX系統編程,所以我可能會誤解事情。

底層動機是使用一個內存Python對象作為欲望stdinstdout kwarg到subprocess.Popen構造,而不必依賴於臨時或存儲器映射的文件。 但是我對一些聰明的技巧不感興趣 - 我真的希望有一個能夠回答所有相關系統調用的Python實現。

你不能。 在Python世界之外的操作系統內核中跟蹤POSIX文件描述符; 你無法在Python代碼中模擬它們。

如果你想要一個可以在傳遞給系統調用時用作文件的類,它需要有一個fileno(),它是一個真正的OS文件描述符。 在不觸及硬盤的情況下執行此操作的一種方法是使用管道,因為它們具有文件描述符,然后系統調用可以寫入這些文件描述符。

我寫了一個類,用另一個答案使用這種技術做了一些事情。 它並沒有真正做你想做的事情,但使用管道的技術應該可以讓你:

import io
import logging
import os
import select
import subprocess
import time
import threading

LOG_FILENAME = 'output.log'
logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG)

class StreamLogger(io.IOBase):
    def __init__(self, level):
        self.level = level
        self.pipe = os.pipe()
        self.thread = threading.Thread(target=self._flusher)
        self.thread.start()

    def _flusher(self):
        self._run = True
        buf = b''
        while self._run:
            for fh in select.select([self.pipe[0]], [], [], 0)[0]:
                buf += os.read(fh, 1024)
                while b'\n' in buf:
                    data, buf = buf.split(b'\n', 1)
                    self.write(data.decode())
            time.sleep(1)
        self._run = None

    def write(self, data):
        return logging.log(self.level, data)

    def fileno(self):
        return self.pipe[1]

    def close(self):
        if self._run:
            self._run = False
            while self._run is not None:
                time.sleep(1)
            os.close(self.pipe[0])
            os.close(self.pipe[1])

這是我第一次涉足POSIX系統編程,所以我可能會誤解事情。

是的。

POSIX文件描述符只是數字 - 它們不是對象,因此您無法覆蓋它們的方法。 例如,0,1和2都是[通常]有效的文件描述符。

“相關系統調用”內置於Linux內核中。 Linux內核本身維護一個列表,將文件描述符映射到某個內部內核對象(它有方法!),但是你不能從Python插入新的文件描述符。 在內核空間中運行的代碼與普通(“用戶模式”)代碼非常不同。

我可以建議您查看subprocess.PIPE,以及stdout / stdin / stderr屬性或subprocess.Popen對象上的communic()方法嗎? 這將允許您啟動子進程,讀取它輸出的數據,並完全控制發送給它的數據。 (我認為這是你真正想做的......)。 如果你很好奇,那么當你玩這個時,你可以查看subprocess.py源代碼,看看它是如何工作的。

有subprocess.PIPE的例子在這里

或者,如果您確實想在Python中實現完整的文件系統,請查看FUSE ,它是Python綁定 FUSE包含一個在內核中運行的C模塊,並處理某個目錄的文件系統請求。 它通過將它們傳遞給用戶空間程序來處理它們,該程序可以用Python編寫。 您可以從單獨的 Python程序中打開這些文件,以獲取文件描述符。 這有點復雜,可能不是初學者開始的最佳場所。

暫無
暫無

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

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