2017-12-05 2 views
3

私は、シャットダウンフックの同時実行のために、「スレッド」、および「信号」のpythonを使用して一つのモジュールがあります:私はDBUSとのGObjectのpython gobject.mainloopゴブルズ信号イベント

を使用して、別のモジュールを持って

signal.signal(signal.SIGINT, self.shutdownhook) 

dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) 
.... 
GObject.threads_init() 
mainloop = GObject.MainLoop() 
mainloop.run() 

これらを別々に実行すると、両方とも正常に動作し、ctrl+cは「KeyboardInterrupt」で終了します。

しかし、それらを一緒に実行すると、メインループは終了しますが、シャットダウンフックは呼び出されません。プロセスはkill -9 pidなしで終了しません。

誰かがこの問題が発生した理由を説明し、最善の方法ここでは、2つのモデルに

を統合することは私の問題を浮き彫りに実施例であるてくださいすることができます。私はCTRL + Cだけでプログラムを終了することはできませんし、この場合もシャットダウンフックは呼び出されません。

import threading 
import signal 
import sys 
from gi.repository import GObject 


def runMainloop(): 
     print('running mainloop') 
     mainloop.run() 

def shutdown(): 
     print('shutdown') 

def readInput(): 
     print('readInput') 
     print(sys.stdin.readline()) 

if __name__ == '__main__': 
     signal.signal(signal.SIGINT, shutdown) 
     signal.signal(signal.SIGTERM, shutdown) 
     GObject.threads_init() 
     mainloop = GObject.MainLoop() 

     mainloopThread = threading.Thread(name='mainloop', target=runMainloop) 
     mainloopThread.setDaemon(True) 
     mainloopThread.start() 
     print('started') 

     inputThread = threading.Thread(name='input', target=readInput) 
     inputThread.start() 
     print('started input') 

答えて

3

誰も興味がありませんので、お試しください。

ただ、同じページ上にあるように:

import signal 
from gi.repository import GObject 

GObject.threads_init() 
mainloop = GObject.MainLoop() 

signal.signal(signal.SIGINT, lambda n, f: mainloop.quit()) 

mainloop.run() 

このコードは動作します:

import signal 
from gi.repository import GObject 

signal.signal(signal.SIGINT, lambda n, f: print("kill")) 

GObject.threads_init() 
mainloop = GObject.MainLoop() 
mainloop.run() 

は、私が最初のシグナルハンドラを登録して、ループを開始しました。奇妙なことは、それが呼ばれていないということです。ただし、結果は - 期待どおりです...

補足として - ドキュメントに従って... mainloopは推奨されていません。それが最初のことです。ここ

編集

MainLoop内部stdinからの読み取りと例です

import signal 
import sys 
from gi.repository import GObject, GLib 

GObject.threads_init() 

def readInput(): 
    print('readInput\n') 
    while True: 
     input = sys.stdin.readline() 
     print(input) 
     if input.strip() == 'exit': 
      print('closing main loop') 
      mainloop.quit() 
      print('terminating thread') 
      return 

if __name__ == '__main__': 
    signal.signal(signal.SIGINT, signal.SIG_DFL) 

    mainloop = GObject.MainLoop.new(None, False) 
    GObject.timeout_add(1000, readInput) 

    # inputThread = threading.Thread(name='input', target=readInput) 
    # inputThread.start() 
    # print('started input') 

    print('running mainloop\n') 
    try: 
     mainloop.run() 
    except KeyboardInterrupt: 
     mainloop.quit() 

.new(None, False)追加CTRL-Cが正常に動作できます。それはhereから、またhereは、GLib/GObjectループとパルスオーディオコントローラを統合する別のスレッドです。ループとの統合dbusに関するサンプルがありますが、どちらの方法を使用するかはわかりません...

+0

ありがとうございますが、それは状況を助けてくれないようです。私はより良い動作例で質問を更新しました。 – pstanton

+0

はい、問題は、 'MainLoop'はすべてのリソースを取り、PythonはGILからシングルスレッドになっているからです... DBusと統合する唯一の方法は、あなたの" stuff "を' MainLoop'イベントシステムに置くことです。ネット上に例がありますが、私はそれに対処するために答えを更新しようとします。 –

+0

ok ..私の他のスレッドは正常に動作しているようですが、信号/シャットダウンは決して起動しないので、混乱しています。だからMainLoopが信号をゴブリングする?たぶん、私はちょうどMainLoopにシャットダウンフックを追加できますか? – pstanton