|
[A5] simple multithread code acts weird |
rocket1
Member #12,826
May 2011
|
hi //thread 1: al_lock_mutex(job); al_start_thread(thread2); for(/*some condition*/){ al_wait_cond(sig,job); } //thread 2: while(1){ al_lock_mutex(job); /* work... */ al_signal_cond(sig); al_unlock_mutex(job); }
i've read the pthreads docs and googled for quite a few hours now. as far as i understand: what happens is that thread2 gets the mutex "while" thread1 is waking up. if i add a small al_rest delay after the wait_cond, i get this behavior 100% of the time. if i add this delay after thread2 unlocks, thread1 gets the mutex first and works like i want it to :p where am i being stupid? |
Elias
Member #358
May 2000
|
rocket1 said: what happens is that thread2 gets the mutex "while" thread1 is waking up. What do you mean? Can you extend the example with some printfs and then say what you expect it to print but what it prints instead? -- |
axilmar
Member #1,204
April 2001
|
The problem is that thread2 sometimes acquires the mutex before thread1 acquires the mutex. You can picture thread2 like this: //thread2 al_lock_mutex(job); /* work... */ al_signal_cond(sig); al_unlock_mutex(job); al_lock_mutex(job); /* work... */ al_signal_cond(sig); al_unlock_mutex(job); ...
As you can see, thread2 unlocks the mutex and then immediately locks it. If you put //thread2 al_lock_mutex(job); /* work... */ al_signal_cond(sig); al_unlock_mutex(job); al_rest(1); al_lock_mutex(job); /* work... */ al_signal_cond(sig); al_unlock_mutex(job); al_rest(1); ... then your code works because thread1 is given a chance to do its work. In order to achieve what you want, you need a semaphore: the worker thread increments the semaphore, and the waiting thread decrements the semaphore or waits for the semaphore to be incremented. |
rocket1
Member #12,826
May 2011
|
thanks for the reply let me do the steps from the start: t1 locks t2 now can lock t1 does not react t2 locks again (same thing..) now t2 apparently takes control forever and t1 still has to do anything. it's in wait_cond limbo for obvious reasons, adding a delay should not be necessary.. |
axilmar
Member #1,204
April 2001
|
There is no guarantee that the thread that is woken up by al_signal_cond will run immediately. What happens under the hood is that the operating system puts the thread in a queue for execution. In the mean time, the other thread gets another execution slot from the operating system, and locks the mutex. You need a semaphore. |
Slartibartfast
Member #8,789
June 2007
|
rocket1 said: t1 does not react
It isn't supposed to. ---- |
rocket1
Member #12,826
May 2011
|
thanks for the replies |
kazzmir
Member #1,786
December 2001
|
wait_cond will atomically lock the mutex before continuing. The issue is that thread 1 never gets to run because whenever its woken up most likely the mutex is locked by t2. |
|