View Single Post
epage's Avatar
Posts: 1,684 | Thanked: 1,562 times | Joined on Jun 2008 @ Austin, TX
#12
Don't forget to initialize threads with gobject or else (I suspect) it holds on to the GIL while mainloop is processing and doesn't allowing other threads to run.

I've been using
Code:
	gtk.gdk.threads_init()
Also if you ever access GTK from outside of your UI thread, you need to be sure to grab the locks. I use the following helper

Code:
@contextlib.contextmanager
def gtk_lock():
	gtk.gdk.threads_enter()
	try:
		yield
	finally:
		gtk.gdk.threads_leave()
Code:
with gtk_lock():
	# do stuff
If you want an example of a threaded PyGTK program, checkout Dialcentral's source
https://garage.maemo.org/scm/?group_id=657

You can also queue tasks to run in the UI thread from your worker thread using idle_add. I use the following helper

Code:
def async(func):
	"""
	Make a function mainloop friendly. the function will be called at the
	next mainloop idle state.
	"""

	@functools.wraps(func)
	def new_function(*args, **kwargs):

		def async_function():
			func(*args, **kwargs)
			return False

		gobject.idle_add(async_function)

	return new_function
For a more advanced PyGTK threading example than Dialcentral I recommend The One Ring. Though it isn't GTK but DBus based, the principles are the same and the helpers I use in go_utils will work in both.
https://garage.maemo.org/scm/?group_id=1078
__________________
770, n810, n900, Ideapad S10-3t
TheOneRing, DialCentral, Gonvert, Quicknote, Multilist, ejpi, nQa, Waters of Shiloah
Programming Blog
 

The Following 3 Users Say Thank You to epage For This Useful Post: