Re: AW: threads & gtk



On Sat, 5 Aug 2006, chabayo wrote:

...fork() creates a copy (or less a copy if kernel has a workaround - i
dont now how that's handled) of memory?

fork() does indeed create a copy. If you have a variable in the original process (= the parent), the child process will also have a variable -- with the same value. Those values are not kept synchronized, however, as the two processes don't share their memory.

(ok, the kernel does optimize things a bit -- it doesn't change how it works and looks to a programmer, it only speeds things up a bit.)

When you are using fork() then you are not using threads. At all. gdk_threads_enter()/gdk_threads_leave() are not relevant. At all.

The child processes must not try to call X directly or indirectly (so no gdk_xxxx() calls). Only the parent process may do that. Perhaps the simplest way of making sure that gets done right is to use simple external programs (which you can then also test in isolation from the command line). In that case, you should really use g_spawn_async_with_pipes(), which also papers over differences between windows and Unix/Linux.

Using fork() can work splendidly but you must know what you are doing.

And then there's the threads way. That can also work splendidly but here you must also really know what you are doing. Some of the rules are the same as with processes: only the main thread should use X and GDK and GTK+ and Gnome (unless you REALLY know what you are doing!). So let the main thread handle the GUI and let the others be worker threads that communicate with the main thread to arrange for it to update the GUI or to be told to go off and do different stuff based on what the user does with the GUI.

But if you are using threads, fork() make no sense and pipes make (almost) no sense, either.

For communication between threads, have a look at GAsyncQueue.
For making sure that only one thread touches shared data structures at a time, have a look at GMutex and g_atomic_int_get() and friends.

After getting /something/ up and running with either threads or with g_spawn_async_with_pipes(), take a moment (read: a couple of days, more like it), to specify, in detail, on paper, precisely what needs to be communicated between the threads.

Consider if the worker threads need to get the main thread to do something when they are done. Consider if they should grab one task at a time from the main thread and complete that or if they should abort whatever they are doing if the main thread has new work for them. Consider what should happen in the user interface if one or both of the worker threads is/are already working on something. Should the option to create more work for them be grayed out while they are busy? Is there anything the threads need to communicate between each other? How about preferences (that you might want to make changeable from the GUI) -- should you lock the entire preferences block while the worker threads are busy so their preferences don't suddenly change under them? (that could be a really nasty problem to find!)

Oh, and see what Wikipedia has to teach about concurrent programming. In particular: reentrancy, data consistency, atomicity of updates/reads, critical sections, deadlocks, and race conditions.

As i mentioned a pipe _works_like_ a file handle all file handles get
dublicated except the 1,2 & 3 ?? - or just pipes? ( ok, just could test
but may miss something )

The parent process can actually choose which file handles get inherited.
But never mind that -- you shouldn't need to know.

-Peter



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]