Subj : Re: How to ensure that a thread runs while another is doing I/O To : comp.programming.threads From : Jomu Date : Mon Jan 10 2005 02:50 pm Anant Padmanath Mudambi wrote: > Hi, > I see the problem with spurious wakeup of thread_1, but what I wanted to > know was something else. If thread_1 is doing I/O and thread_2 is > runnable, how can we ensure that thread_2 executes while thread_1 is > waiting for the I/O to finish. My test code shows these 2 outcomes: > > 1] thread_1 starts file write > thread_2 starts CPU bound work > thread_2 finishes CPU bound work > thread_1 finishes file write > > OR > > 2] thread_1 starts file write > thread_1 finishes file write > thread_2 starts CPU bound work > thread_2 finishes CPU bound work > > I want to know if we can guarantee outcome 1] all the time. 1. Your process (one which contains these threads) is probably not only one on system, so scheduling is probably very random all around. And, as you don't (you don't, I hope :)) have badly placed mutexes which would block execution of your threads, your threads are running at "max speed". Just don't worry about system scheduler. 2. Your I/O is not synchronous, if you didn't made it such. So, your write is probably all in buffers (meaning it's "finished" fast). If you want sync I/O, it's another problem and (more important) special API on most systems. > > Thank you, > Anant. > > On Sun, 9 Jan 2005, Joseph Seigh wrote: > > > On Sun, 9 Jan 2005 19:56:32 -0500, Anant Padmanath Mudambi wrote: > > > > > Hi all, > > > Consider this psuedo code: > > > > > > M1,M2 : mutexes C: condition variable > > > > > > thread_1 > > > { > > > mutex_lock(M1); > > > mutex_lock(M2); > > > create thread_2; > > > cond_wait(C, M1); > > > mutex_unlock(M1); > > > mutex_unlock(M2); > > > big write to a file on disk; > > > join(thread_2); > > > } > > > > > > thread_2 > > > { > > > mutex_lock(M1); > > > CPU-bound work #1; > > > mutex_unlock(M1); > > > cond_signal(C); > > > mutex_lock(M2); > > > CPU-bound work #2; > > > } > > > > > > By putting printf()s in this code I saw that after thread_2 signals C, > > > sometimes the "CPU-bound work #2" executes while thread_1 is waiting for > > > the file write to finish and sometimes it executes AFTER the whole file > > > write finishes. > > > > > > How can I ensure that thread_2 always continues to execute as soon as > > > possible without waiting for the whole file write in thread_1 to finish? > > > Assume these are the only 2 user threads on the system. > > > > > > > The problem you are likely seeing is that you are using the condition > > variable incorrectly. You need to use it in conjunction with a testable > > data condition so you can correctly deal with spurious wakeups, which is > > what you're probably seeing with thread 1 starting i/o without actually > > being explicitly signaled. For instance, use a "done" flag to indicate the > > work is done. so your thread 1 wait becomes > > > > while (!done) > > cond_wait(C, M1); > > > > and your thread 2 signal becomes > > > > done = true; > > mutex_unlock(M1); > > cond_signal(C); > > > > Your signal can be with or without the lock held after you've set the flag > > but setting the flag must be with the lock held. > > > > Also, doing a condition wait on the not most recently acquired lock is > > a BAD habit. Thread 1 is acquiring lock M2 while M1 held and then > > reacquiring M1 on exit from wait while M2 is held. You don't have > > a consistent lock hierarchy. If any other thread tried to acquire > > both locks you could get deadlock. Get out of that habit unless you > > want to learn how to debug deadlocks. So switch the order of the first > > two statements in thread 1. > > > > - > > Joe Seigh > > .