3

Arduino からいくつかのパラメーターを読み取り、データベースに保存する Python プログラムがあります。シリアル ポートは、次のように設定して使用します。

ser = serial.Serial(port=port, baudrate=9600)
ser.write('*')
while 1 :
    ser.write('*')
    out = ''
    # Let's wait one second before reading output (let's give device time to answer).
    time.sleep(1)
    while ser.inWaiting() > 0:
        out += ser.read(1)
    if out != '': 
        etc ... handling data

(Arduinoはスターを受信するとデータ文字列を返すように設定されています。) これをデーモンとして書き換えたいので、python-daemonライブラリを使用しています。init部分では、ポート名を定義するだけで、次のようになります。

def run(self):
    self.ser = serial.Serial(port=self.port,baudrate=9600)
    while True:
        self.ser.write('*')
        out = ''
        # Let's wait one second before reading output (give device time to answer).
        time.sleep(1)
        while self.ser.inWaiting() > 0:
            out += self.ser.read(1)
        if out != '':
            etc ...

App-object 内でシリアル処理を実行していることを除いて、すべて同じです。最初のバージョンは問題なく動作しますが、後者を実行しようとすると、

File "storedaemon.py", line 89, in run
 while self.ser.inWaiting() > 0:
 File "/usr/lib/python2.7/dist-packages/serial/serialposix.py", line 435, in inWaiting
 s = fcntl.ioctl(self.fd, TIOCINQ, TIOCM_zero_str)
 IOError: [Errno 9] Bad file descriptor

新しいオブジェクト内にコードを放り込んだことを除いて、何が変更されたかを確認できません。initと runの両方で初期化を試みましたが、結局同じ結果になりました。

(完全なスクリプトは、hhv3.sickel.net/b/storedata.pyおよびで入手できますhhv3.sickel.net/b/storedaemon.py。)

4

1 に答える 1

2

アプリのデーモン化中は、stdin、stderr、および stdout を除くすべてのファイル ハンドラーが閉じられます。これには への接続が含まれ、/dev/logその後 fd エラーで失敗します (したがって、これはシリアル fd とは関係がなく、代わりにハンドラーのソケットと関係があるように見えます)。

この FD を除外リストに追加する必要があります。

class App():
    def __init__(self):
        ...
        self.files_preserve = [handler.socket]
        ...

または、デーモン プロセスが fork された後にハンドラーをセットアップします。

class App():
    def run(self):
        handler = logging.handlers.SysLogHandler(address = '/dev/log')
        my_logger.addHandler(handler)
        my_logger.debug(appname+': Starting up storedata')
        ...

私のテストでは、どちらのバージョンも問題なく動作しました。

于 2013-04-26T21:16:34.697 に答える