Thothadri Rajesh
Thothadri Rajesh

Reputation: 522

gtk threads safety python

I have a basic doubt about threads in gtk. I would like to run two functions in parallel in gtk . Is it ok if i use gobject_timeoutadd for the same . if yes, should i use gtk.thread_enter and gtk.thread_leave ?

my idea of the program looks like this

import gtk,gobject

class Gtk_main:

    def __init__(self):
        self.a=2
        self.b=3
        gobject.timeout_add(1000,self.test_1)
        gobject.timeout_add(1000,self.test_2)        


    def test_1(self):

        return True

    def test_2(self):

        return True



Gtk_main()
gobject.threads_init()
gtk.gdk.threads_init()
gtk.main()

This code is just an example. When i really used gtk.thread_enter and gtk.thread_leave, the program hangs. So i wanted to clear my understanding about gtk threads .

Thanks in Advance, thothadri

Upvotes: 0

Views: 1216

Answers (3)

mg.
mg.

Reputation: 8012

Your example hangs because gtk.main() calls gdk_threads_leave() before it enters the loop and gdk_threads_enter() after it exits the loop so if you call gtk.gdk.threads_init() your code should be something like the following one.

...
gobject.threads_init()
gtk.gdk.threads_init()
Gtk_main()
gtk.gdk.threads_enter()
gtk.main()
gtk.gdk.threads_leave()

PS. I am not sure that Gtk_main() must go after thread initialization but I think it will not hurt.

As ptomato said, timeout_add() is not thread safe but this is a problem only if you need to call gtk functions from a different thread. A simple approach is:

import functools


def thread_safe(func):
    @functools.wraps
    def wrapper(*args, **kwds):
        gtk.gdk.threads_enter()
        try:
            return func(*args, **kwds)
        finally:
            gtk.gdk.threads_leave()
    return wrapper

threads_timeout_add = thread_safe(gobject.timeout_add)

Upvotes: 1

ptomato
ptomato

Reputation: 57920

If you use only timeouts, then you don't need to use GDK threads.

If you use both timeouts and threads, then you don't need to call threads_enter() and threads_leave() in your timeout callback.

Upvotes: 1

wolfv
wolfv

Reputation: 323

I always used Python and not GTK Threads in my programs, which worked well.

However, it's still necessary to gobject.threads_init() and maybe even gtk.gdk.threads_init() depending on your GTK version.

Also you need to import threading, of which you'll find a superb documentation at the official python docs.

Upvotes: 0

Related Questions