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 <[email protected]>

> 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
>
>  i've also attached my code.  the program is fairly short, so should be
> easy to follow.  But to make a little more obvious from the algorithm above:
>
>    - M = main() (file pqlxPNG.c, line 31)
>    - TM = systemPDF() (file systemPDF.c, line 149)
>    - T*n* = getPdfPng() (file systemPDF.c, line 99; threads created at
>    line 280 in TM routine)
>    - TF = finishPdfPng() (file systemPDF.c, line 139)
>    - static mutex = mainMutex (file pqlxPNG.c, line 28; file systemPDF.c,
>    line 74)
>    - (another static mutex, named myMutex, is used for other reasons,
>    ignore this one)
>
> the question, of course, is will this work under windows?  not sure, my
> code is only run under linux systems and it works fine there.
>
> cheers,
>
> richard
>
> On Tue, Jul 7, 2009 at 9:56 AM, Dov Grobgeld <[email protected]>wrote:
>
>> Thanks a lot for the help.! I have now solved the problem by
>> introducing a GCond,called C below, into the flow. For posterity, here
>> is the modified flow, which is actually a general model of a
>> client-server interaction between a worker thread and the gui thread.
>>
>>    * W locks j->M through g_mutex_lock(j->M) so that G will not send
>> the condition signal until we are ready for it.
>>    * W fills in j with various info to display.
>>    * W calls g_idle_add(GSourceFunc(cb_update_job), j) to indicate to
>> G that there is info to display.
>>    * W waits on C through g_cond_wait(j->C, j->M). This will unblock
>> j->M and allow G to continue.
>>    * G is called in cb_update_job().
>>   * G updates the gui, also possibly updates j based on GUI interaction.
>>   * G does g_mutex_lock(j->M) which causes it to wait until W has
>> reached g_cond_wait().
>>   * G sends a condition signal through g_cond_signal(j->C)
>>   * G does g_mutex_unlock(j->M). This will allow W to take the lock
>> in g_cond_wait().
>>    * W wakes up and does a g_mutex_unlock(j->M) as it no longer needs
>> the lock on the mutex.
>>    * W examines the return info that G filled in into j and contiues
>> or aborts its operation.
>>
>> Quite complex I have to admit. Is there a simpler way to solve the
>> same problem (query/response)?
>>
>> Regards,
>> Dov
>>
>> 2009/7/7 Chris Vine <[email protected]>
>> >
>> > On Mon, 6 Jul 2009 17:13:07 +0300
>> > Dov Grobgeld <[email protected]> wrote:
>> >
>> > > I'm having a problem with GMutex under Windows that don't lock. The
>> > > behaviour is definitely different from that under Linux.
>> > >
>> > > The system is composed of to threads. A gui thread G and a worker
>> > > thread W. The ping pong between the threads via a mutex j->M should
>> > > work as follows. j is a job data structure that carries info between
>> > > the worker thread and the gui thread.
>> > >
>> > >    1. W locks j->M through g_mutex_lock(j->M) so that a subsequent
>> > > lock will block.
>> > >    2. W fills in j with various info to display.
>> > >    3. W calls g_idle_add(GSourceFunc(cb_update_job), j) to indicate
>> > > to G that there is info to display.
>> > >    4. W blocks on M through a second call to g_mutex_lock(j->M)
>> > >    5. G is called in cb_update_job() and updates the gui, also
>> > > possibly updates j, and then does g_mutex_unlock(j->M)
>> > >    6. W wakes up and does a g_mutex_unlock(j->M) as it no longer
>> > > needs the lock on the mutex.
>> > >    7. W examines the return info that G filled in into j and contiues
>> > > or aborts its operation.
>> > >
>> > > The problem on Win32 is that g_mutex_lock in 4 doesn't block and the
>> > > thread continues, which eventually will cause the system to crash.
>> > >
>> > > Is something supposed to be different under Windows, or should I file
>> > > a bug?
>> >
>> > This won't work.  Mutexes have ownership once locked.  An unlock
>> > operation on a mutex must be carried out by the same thread that locked
>> > it.
>> >
>> > You could use condition variables to achieve what you want.  It would
>> > also be wise to read up a little more on threading, and in particular
>> > pthreads (which GThreads mimic).
>> >
>> > Chris
>> >
>> _______________________________________________
>> gtk-list mailing list
>> [email protected]
>> http://mail.gnome.org/mailman/listinfo/gtk-list
>>
>
>
_______________________________________________
gtk-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/gtk-list

Reply via email to