2015-02-11 40 views
2

我目前正在尝试创建一个python脚本,它必须使用GObject.MainLoop()与蓝牙客户端进行通信。 我把循环放在一个新的线程中,以便不会阻塞剩余的代码。Python DBusGMainLoop内线程和尝试和catch块

一切工作正常,直到我试图用Control + C退出程序。 如果我点击这个命令,第二个try和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 

现在我想知道为什么 “打印(” 主持人:一个KeyboardInterrupt “)” 没有得到执行。此外,我不确定如何解决所述的警告。

希望你能帮助!

回答

2

事实上,我自己能够解决这个问题。

您只需将MainLoop()放入主线程,并在新线程(myT)中启动当前执行“print(”Host:每1秒打印一次“)”的其他操作。所以你必须从上面的代码中改变线程。 然后,如果KeyboardInterrupt发生,您必须手动退出第二个线程(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 attempting 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 

参见: Closing all threads with a keyboard interrupt