簡體   English   中英

在一個模塊中打開命名管道,在另一個模塊中讀取

[英]Opening named pipe in one module, reading in the other

我正忙着為我的一個項目找出一些東西,但我還掛了一個問題:

我正在使用FIFO操作從一個模塊向另一個模塊發送“信號”(簡單T / F)。 一個模塊打開FIFO以寫入它,另一個模塊打開FIFO以從中讀取。 這里的目標是在寫入模塊接收到命令時立即讀取並顯示讀取模塊。 寫入模塊打開FIFO,但讀取模塊似乎不這樣做。

我正在努力做甚么可能嗎? 我試圖在_threads中旋轉兩個操作,以便在每個模塊中保持多個進程。 請注意,為了簡潔起見,這兩個模塊都在我沒有包含的類中(解釋'self')。

原始發送模塊

def pipe_relay(self):
    FIFO = 'pipe_relay'
    thread_num = num

    try:
        os.mkfifo(FIFO)
    except OSError as oe:
        if oe.errno != errno.EEXIST:
            raise

    while self.relay_switch:
        print("Opening FIFO...")
        with open(FIFO) as fifo:
            print("FIFO opened")
            while self.relay_switch:
                data = fifo.write(signal)
                if len(data) == 0:
                    print("Writer is closed")
                    break
                print('Write: "{0}"'.format(data))

更新發送模塊

我意識到我不想用我投入的數據連續寫入FIFO,所以我刪除了while()語句。 現在,似乎FIFO根本不會打開......


def pipe_relay(self, num, signal):
    FIFO = 'pipe_relay'
    thread_num = num

    try:
        os.mkfifo(FIFO)
    except OSError as oe:
        if oe.errno != errno.EEXIST:
            raise

    print("Opening FIFO...")

    # does not proceed past this point

    with open(FIFO, mode = 'w') as fifo:
        print("FIFO opened")
        data = fifo.write(signal)
        if len(data) == 0:
            print("Writer is closed")
        print('Write: "{0}"'.format(data))
        fifo.close()

接收模塊

def pipe_receive(self):
    FIFO = 'pipe_relay'

    try:
        os.mkfifo(FIFO)
    except OSError as oe:
        if oe.errno != errno.EEXIST:
            raise   

    # module proceeds to here, but no further

    with open(FIFO) as fifo:
        print("FIFO opened (receiver)")
        while True:
            data = fifo.read()
            if len(data) == 0:
                print("Writer is closed")
                break
            print('Read signal: "{0}"'.format(data))
            self.DISPLAY['text'] = data
    print("this is in 'pipe_receieve'")

編輯

運行Ubuntu 17.04。 該項目是為Python 3.5解釋器編寫的。

以下是使用Python 3.5.2編寫的簡單send和get片段。
注釋掉fifo.flush()行並查看行為上的差異。
使用flush ,get代碼與發送代碼一起運行。
沒有它,get代碼在fifo關閉之前不會做出反應

send.py

import sys, os, time

path = "/tmp/my.fifo"
try:
    os.mkfifo(path)
except:
    pass
try:
    fifo = open(path, "w")
except Exception as e:
    print (e)
    sys.exit()
x = 0
while x < 5:
    fifo.write(str(x))
    fifo.flush()
    print ("Sending:", str(x))
    x+=1
    time.sleep(3)
print ("Closing")
fifo.close()
try:
    os.unlink(fifo)
except:
    pass

get.py

import os, sys

path = "/tmp/my.fifo"
try:
    fifo = open(path, "r")
except Exception as e:
    print (e)
    sys.exit()
while True:
    r = fifo.read(1)
    if len(r) != 1:
        print ("Sender Terminated")
        break
    print ("Received:", r)
fifo.close()

我有點驚訝的是代碼沒有引發異常。 在您的編寫器中,您執行常規open(FILO) ,而不指定mode參數。 根據文檔mode默認為r (只讀),所以我希望fifo.write(signal) IOError 異常是否被某處抓獲?

無論哪種方式,您都應該向編寫器端添加mode="w"以打開FIFO進行寫入。

除了要求發送模塊的'w'選項外,您可能還遇到了發送或接收器未連接的問題。 為了使另一個進程能夠使用fifo,發送方和接收方都必須打開fifo句柄。

請參閱fifo上的linux 文檔 如果接收器沒有監聽,你會得到一個SIGPIPE,通常會終止一個進程,但在python的情況下,它將等到接收器連接。

如果您的發件人已經死亡且收聽者仍處於活動狀態,則會收到EOF並停止閱讀。

暫無
暫無

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

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