On Tue, 7 Jul 2009 12:19:27 +0300 Dov Grobgeld <dov.grobgeld@xxxxxxxxx> wrote: > Hi Richard, > > As far as I understand from your pseudo code you are doing the same > mistake as I did in my first effort, namely to lock the same mutex > twice in the same thread, and to expect that the second invocation > will block until another thread releases the mutex. You do this in 3 > and in 6. Indeed I, like you, found out that this works under Linux, > but Tor pointed out that the documentation states that this is > undefined behaviour, and indeed it does not work under Windows. > That's why I used the GCond instead. > > Regards, > Dov > > 2009/7/7 richard boaz <ivor.boaz@xxxxxxxxx> > > > Hi Dov, > > > > I have solved this in a diferent way that does seem to be a bit > > easier, and is a little more like your first algorithm. (indeed, > > your second solution does seem a bit convoluted.) > > > > First, different from your mutex, I'm using a static mutex that is > > referenced everywhere. And, my program is not one of a GUI and a > > worker thread, but between the main program and multiple worker > > threads, though the general idea is the same. > > > > The general algorithm is: > > > > 1. main thread (M) does program setup > > 2. M then calls routine (TM) directly to set up the worker > > threads (i.e, TM is NOT a separate thread from M) > > 3. TM immediately locks the static mutex > > 4. TM then creates as many threads (T*n*) as there are CPU's > > available 5. TM returns control to M > > 6. M: upon return from TM, immediately calls > > g_static_mutex_lock(), blocking flow since this has already been > > locked in step 3. 7. T*n*: all threads do their work until > > complete. Once complete, each thread calls a common thread finish > > routine (TF) that keeps track of when all threads have completed. > > 8. TF: Once all threads are complete, static mutex locked in > > step 3 is unlocked. > > 9. M: block from step 6 can now continue [snip] > > richard Richard's approach can be made to work on unix-like OSes (ie those where the underlying threading is pthreads) because it respects mutex ownership of a locked mutex and the result of double locking a non-recursive mutex is defined in pthreads if you choose PTHREAD_MUTEX_NORMAL as the mutex type, as deadlocking is mandatory in that case, but not otherwise (this is from the POSIX standard): "PTHREAD_MUTEX_NORMAL: This type of mutex does not detect deadlock. A thread attempting to relock this mutex without first unlocking it shall deadlock. Attempting to unlock a mutex locked by a different thread results in undefined behavior. Attempting to unlock an unlocked mutex results in undefined behavior. PTHREAD_MUTEX_ERRORCHECK This type of mutex provides error checking. A thread attempting to relock this mutex without first unlocking it shall return with an error. A thread attempting to unlock a mutex which another thread has locked shall return with an error. A thread attempting to unlock an unlocked mutex shall return with an error. PTHREAD_MUTEX_RECURSIVE A thread attempting to relock this mutex without first unlocking it shall succeed in locking the mutex. The relocking deadlock which can occur with mutexes of type PTHREAD_MUTEX_NORMAL cannot occur with this type of mutex. Multiple locks of this mutex shall require the same number of unlocks to release the mutex before another thread can acquire the mutex. A thread attempting to unlock a mutex which another thread has locked shall return with an error. A thread attempting to unlock an unlocked mutex shall return with an error. PTHREAD_MUTEX_DEFAULT Attempting to recursively lock a mutex of this type results in undefined behavior. Attempting to unlock a mutex of this type which was not locked by the calling thread results in undefined behavior. Attempting to unlock a mutex of this type which is not locked results in undefined behavior." However, GThreads most likely uses PTHREAD_MUTEX_DEFAULT in which case the fact that it works is a matter of luck (although all implementations I have seen do in fact deadlock with PTHREAD_MUTEX_DEFAULT). Dov's implementation also suffered from the problem of a non-owning thread unlocking the mutex, which is undefined behaviour for all mutex types. Altogether, it would be better to use either POSIX semaphores (for which Dov's approach would be fine as semaphores are not owned) but which are not found in GThreads, or condition variables, which are. Chris _______________________________________________ gtk-list mailing list gtk-list@xxxxxxxxx http://mail.gnome.org/mailman/listinfo/gtk-list