【问题标题】:Python threads don't work with pygobject?Python 线程不适用于 pygobject?
【发布时间】:2013-05-01 04:54:10
【问题描述】:

看看这个简单的python gobject程序:

import threading
import gobject
import time

def f():
    while True:
        print "HELLO"
        time.sleep(1)
threading.Thread(target=f).start()

gobject.MainLoop().run()

它产生一个每秒输出“HELLO”的线程,然后进入 gobject 主循环。问题是它实际上并没有做任何事情。为什么?

$ python a.py 
[...]

但是,如果我按 CTRL+C,它就会开始工作。此外,删除程序中的最后一行 (gobject.MainLoop().run()) 使其工作。为什么?

$ python a.py 
^CTraceback (most recent call last):
  File "a.py", line 11, in <module>
    gobject.MainLoop().run()
KeyboardInterruptHELLO

HELLO
HELLO
HELLO
[...]

看看第二个程序,它和第一个程序完全一样,只是它告诉 gobject 每秒运行一次函数g。这种工作方式,产生的线程每隔一段时间运行一次,而不是从不运行。为什么?

import threading
import gobject
import time

def f():
    while True:
        print "HELLO"
        time.sleep(1)
threading.Thread(target=f).start()

def g():
    print "yo"
    return True
gobject.timeout_add_seconds(1, g)

gobject.MainLoop().run()

运行它:

$ python b.py 
HELLOyo

yo
yo
yo
 HELLO
yo
yo
yo
yo
yo
yo
yo
 HELLO
yo
yo
yo
yo
^CTraceback (most recent call last):
  File "b.py", line 16, in <module>
    gobject.MainLoop().run()
KeyboardInterrupt
HELLO
HELLO
HELLO
HELLO
HELLO

再一次,按 CTRL+C 使生成的线程工作。为什么?

这是使用库 pygobject-2.28.6。

【问题讨论】:

    标签: python asynchronous concurrency pygobject gobject


    【解决方案1】:

    使用gobject时需要initialize threading。为此,请致电

    gobject.threads_init()
    

    【讨论】:

    • 嗯,这似乎解决了它,但也许这只是一个巧合,也许是因为改变了并发事件的顺序。我发现一个库会破坏整个运行时是很荒谬的,除非你在使用它之前在其中调用一个函数。此外,“对于希望使用 Python 线程与 GNOME 平台交互的应用程序,必须在运行或创建线程和启动主循环之前调用 GObject.threads_init()。”不包括我的情况,因为我只使用主线程中的 gobject。
    • 即使对于 C 语言中的 glib,“如果您在多个线程中使用 GLib,则必须通过调用 g_thread_init() 来初始化线程系统。” (developer.gnome.org/glib/2.30/glib-Threads.html#g-thread-init)
    • 我不完全知道为什么 glib 主循环会阻塞所有其他线程,我猜想它不会在运行时释放 GIL,除非你正确初始化它。但我真的找不到任何支持这一点的参考资料(除了here)。
    • github.com/GNOME/pygobject/blob/master/gi/overrides/GLib.py#L53 说:“从 3.11 版开始,不再需要调用threads_init。见:wiki.gnome.org/PyGObject/Threading
    猜你喜欢
    • 2016-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-29
    • 2021-12-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多