4

現在、GObject.MainLoop() を使用して Bluetooth クライアントと通信する必要がある Python スクリプトを作成しようとしています。残りのコードをブロックしないように、ループを新しいスレッドに入れました。

Control + C でプログラムを終了しようとするまで、すべて正常に動作します。このコマンドを実行すると、2 番目の try and catch ブロック ("Host:...") が実行されないようです。

スクリプト例:

import time
import threading

from dbus.mainloop.glib import DBusGMainLoop

try:
    from gi.repository import GObject
except ImportError:
    import gobject as GObject

DBusGMainLoop(set_as_default=True)

def myThread(a):
    try:
        GObject.threads_init()
        mainloop = GObject.MainLoop()
        mainloop.run()

    except KeyboardInterrupt:
        mainloop.quit()
        print("Thread: KeyboardInterrupt")
    return

try:
    myT = threading.Thread(target=myThread, args=(1,))
    myT.start()

    while 1:
        print("Host: Print every 1 sec")
        time.sleep(1)
except KeyboardInterrupt:
    print("Host: KeyboardInterrupt")

スクリプトの出力:

Host: Print every 1 sec
Host: Print every 1 sec
^CHost: Print every 1 sec
Thread: KeyboardInterrupt
/usr/lib/python2.7/dist-packages/gi/types.py:113: Warning: Source ID 1 was not found when attempting to remove it
  return info.invoke(*args, **kwargs)
Host: Print every 1 sec
Host: Print every 1 sec
Host: Print every 1 sec
Host: Print every 1 sec

Process finished with exit code -1

なぜ「print("Host: KeyboardInterrupt")」が実行されないのか疑問に思っています。さらに、記載されている警告を解決する方法がわかりません。

あなたが助けてくれることを願っています!

4

1 に答える 1

4

実際、私は自分で問題を解決することができました。

メイン スレッドに MainLoop() を配置し、現在 "print("Host: Print every 1 sec")" を新しいスレッド (myT) で実行している他のアクションを開始するだけです。したがって、上記のコードからスレッドを変更する必要があります。その後、KeyboardInterrupt が発生した場合は、2 番目のスレッド (myT) を手動で終了する必要があります。

「print("Thread: KeyboardInterrupt")」のみが呼び出される理由は、MainLoop を使用すると、それを呼び出すプロセスが「新しいメイン トレッド」と見なされるためです。

ただし、エラーを取り除く方法はまだわかりません。

(process:2429): GLib-CRITICAL **: Source ID 1 was not found when attempting to remove it

投稿「GLib-CRITICAL **: Source ID XXX was not found when attempts to remove it」によると、警告は問題ではないため、無視します。これが、この投稿につまずく人の助けになることを願っています!

例:

import time
import threading

from dbus.mainloop.glib import DBusGMainLoop

try:
    from gi.repository import GObject
except ImportError:
    import gobject as GObject

DBusGMainLoop(set_as_default=True)

def myThread(run_event):
    while run_event.is_set():
        print("Thread: Print every 1 sec")
        time.sleep(1)
    print("Thread: Exit")
    return

try:
    run_event = threading.Event()
    run_event.set()

    myT = threading.Thread(target=myThread, args=(run_event,))
    myT.start()

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

except (KeyboardInterrupt, SystemExit):
    mainloop.quit()
    run_event.clear()
    myT.join()
    print("Host: KeyboardInterrupt")

出力:

Thread: Print every 1 sec
Thread: Print every 1 sec
^CThread: Exit
Host: KeyboardInterrupt

(process:2429): GLib-CRITICAL **: Source ID 1 was not found when attempting to remove it

参照: キーボード割り込みですべてのスレッドを閉じる

于 2015-02-12T11:45:23.957 に答える