I created two threads-- thread1 is for writing to a file and thread2 is for reading from the same file, in the main thread. Writing to a file may take a while so during the writing, I wish to read the file in the mean time(well in some sense). My problem is that which thread that is going to be executed is random. So it messed up, for example, reading a file before anything is written to a file. How can I ensure that thread1 is going to be executed first, then switch to thread2, then switch to thread1, etc. Please give me some clues!
cilu
July 5th, 2005, 02:08 PM
Take a look at WaitForSingleObject.
drewdaman
July 5th, 2005, 02:09 PM
you will have to have some sort of variable accessible by both threads so you know how far you can read... or at least i ca't think of a better way!
i guess you are not looking for things like events, critical sections, semaphores.. not too clear on exactly what you're doing... but in case you don't already know how to use these, take a look and see if they help! the waitforsingleobject() thing cilu mentioned waits for these things...
Thanks for your suggestions. Actually, I tried to use Waitforsingleobject on one thread. But once it is returned from Waitforsingleobject, the waited thread will never have a chance to be executed again.I expect thread1 to be executed FIRST, then the program can swith between thread1 and thread2(reading and writing). I don't expect thead2 be executed after thread1 is completely done. Any ideas how to do that? Thank you very much!
you will have to have some sort of variable accessible by both threads so you know how far you can read... or at least i ca't think of a better way!
i guess you are not looking for things like events, critical sections, semaphores.. not too clear on exactly what you're doing... but in case you don't already know how to use these, take a look and see if they help! the waitforsingleobject() thing cilu mentioned waits for these things...
drewdaman
July 5th, 2005, 04:51 PM
larry, i think you should post some code so we can take a look at what you're doing.. things are much clearer that way and its usually much quicker to fix the problem.
LarryChen
July 5th, 2005, 05:10 PM
Okey, I attach my code this time. If you have any questions with my code, please let me know. Thank you very much!
larry, i think you should post some code so we can take a look at what you're doing.. things are much clearer that way and its usually much quicker to fix the problem.
Andreas Masur
July 5th, 2005, 05:13 PM
Thanks for your suggestions. Actually, I tried to use Waitforsingleobject on one thread. But once it is returned from Waitforsingleobject, the waited thread will never have a chance to be executed again.I expect thread1 to be executed FIRST, then the program can swith between thread1 and thread2(reading and writing). I don't expect thead2 be executed after thread1 is completely done. Any ideas how to do that? Thank you very much!
Well...I am not sure whether I understand the above...but I would use two events which would be set in an alternating way...
// Pseudo code
Event one
Event two
Thread One
{
while(true)
{
// Wait for Event one
// Reset Event one
// Do the stuff
// Set Event two
}
}
Thread Two
{
while(true)
{
// Wait for Event two
// Reset Event two
// Do the stuff
// Set Event one
}
}
Andreas Masur
July 5th, 2005, 05:19 PM
Okey, I attach my code this time. If you have any questions with my code, please let me know. Thank you very much!
Two obvious points (didn't look that closely)...
You are using critical sections which are being used to synchronize access to shared data but not execution of threads
These critical section are local to the function which means they are different objects. In order to syncronize, you would need to make the same object available to all the threads.
You don't want to add the whole MFC just because of any synchronization class...
How should these threads be synchronized? In other words, when should what thread execute?
LarryChen
July 5th, 2005, 05:36 PM
Thanks for your suggestions! You are right, I will declare critical section as a global object. But at this point, I am looking for some means to switch between two threads execution.
Two obvious points (didn't look that closely)...
You are using critical sections which are being used to synchronize access to shared data but not execution of threads
These critical section are local to the function which means they are different objects. In order to syncronize, you would need to make the same object available to all the threads.
You don't want to add the whole MFC just because of any synchronization class...
How should these threads be synchronized? In other words, when should what thread execute?
Andreas Masur
July 6th, 2005, 01:57 AM
Thanks for your suggestions! You are right, I will declare critical section as a global object. But at this point, I am looking for some means to switch between two threads execution.
You didn't answer my questions...
How should these threads be synchronized? In other words, when should what thread execute?
pranavsharma
July 7th, 2005, 09:34 AM
You can use Crtical Sections but they will be some complicated . For easier implementation you can use Global flag variable for the same to provide the sync.
Arjay
July 7th, 2005, 12:35 PM
Thanks for your suggestions. Actually, I tried to use Waitforsingleobject on one thread. But once it is returned from Waitforsingleobject, the waited thread will never have a chance to be executed again.I expect thread1 to be executed FIRST, then the program can swith between thread1 and thread2(reading and writing). I don't expect thead2 be executed after thread1 is completely done. Any ideas how to do that? Thank you very much!I've waited a bit to chime in here, just to see of there could be a clarification of what you are looking for.
At any rate, it seems you need to have each thread alternate - that is, one thread writes for a bit and then the other thread reads and so on. Correct? If this is true, then you aren't going to derive any benefit from using two threads.
Why? One of the main benefits of threading is to allow continuous processing of work. Consider a single threaded word processor print operation. In a single threaded app when the user prints, the user can't type until the printing has completed. In a multithreaded app, the user can continue to type while the printing is occuring because a second thread is performing the printing in parallel [with the typing thread] - in other words the threads are operating asynchronously.
What you are describing - one thread writes for a while and then the second thread gets to read is really a synchronous operation so you may be better off doing this in one thread.
On the other hand, depending on more details required for you design you may not.
So let's look at doing it with two threads. Just create the two threads (T1 & T2) and use two events (E1 & E2) to synchronize the threads. T1 will represent the writing thread and T2 will be the reading thread.
Internally in a loop, each thread waits on the 'opposite' event (T1 waits on E2 and T2 waits on E1). You'll first create both events and threads and initially set the E2 event which causes T1 to execute. You'll let T1 execute for a while and then call SetEvent on E1. T1 is at the end of its loop and goes back to waiting on E2. Since E1 has been set, T2 wakes up and starts reading, when you've decided that it's finished reading, you'll set E2 (so T1 can wake up) and so on.
Something that I haven't mentioned is that you probably need to track the current read and write positions of the file. These variables will need to be protected which can be easily done with the InterlockExhange family of functions.
Arjay
LarryChen
July 7th, 2005, 11:31 PM
Thanks so much for your useful comments. I have modified my code but it still didn't work. I already attach the modified code with this post. There is two major problems. First of all, the program is in a dead loop at the end. Secondly, after writing thread is executed first, if you debug the program, you will find a string is indeed written into the file by checking int n = fwrite((void*)s,sizeof(char),count,output). Then when reading thread is executed, fgets(buffer,128,output) always returns NULL meaning that nothing has been written into output. That is very strange. Please help me with the problems! Thank you very much!
I've waited a bit to chime in here, just to see of there could be a clarification of what you are looking for.
At any rate, it seems you need to have each thread alternate - that is, one thread writes for a bit and then the other thread reads and so on. Correct? If this is true, then you aren't going to derive any benefit from using two threads.
Why? One of the main benefits of threading is to allow continuous processing of work. Consider a single threaded word processor print operation. In a single threaded app when the user prints, the user can't type until the printing has completed. In a multithreaded app, the user can continue to type while the printing is occuring because a second thread is performing the printing in parallel [with the typing thread] - in other words the threads are operating asynchronously.
What you are describing - one thread writes for a while and then the second thread gets to read is really a synchronous operation so you may be better off doing this in one thread.
On the other hand, depending on more details required for you design you may not.
So let's look at doing it with two threads. Just create the two threads (T1 & T2) and use two events (E1 & E2) to synchronize the threads. T1 will represent the writing thread and T2 will be the reading thread.
Internally in a loop, each thread waits on the 'opposite' event (T1 waits on E2 and T2 waits on E1). You'll first create both events and threads and initially set the E2 event which causes T1 to execute. You'll let T1 execute for a while and then call SetEvent on E1. T1 is at the end of its loop and goes back to waiting on E2. Since E1 has been set, T2 wakes up and starts reading, when you've decided that it's finished reading, you'll set E2 (so T1 can wake up) and so on.
Something that I haven't mentioned is that you probably need to track the current read and write positions of the file. These variables will need to be protected which can be easily done with the InterlockExhange family of functions.
Arjay
Arjay
July 8th, 2005, 03:10 PM
Larry, you need to pass the event handles to each of your thread procedures. Plus you need to wait for the events in each thread proc, and set each event so the opposite thread wakes up appropriately.
I've attached a sample app, which simulates the reading and writing to a file. Although it doesn't actually perform any file reading or writing, it does keep track of a file read/write positions. So it should be somewhat simple to convert to real file operations.
Be warned that this code has been written in more of a C++ style where the thread procs are static members of a class. I chose this method because it makes things much easier to pass data around between threads.
P.S. I wrote this in VC7.1 so if you are using an earlier compiler just copy the code out of AltThreads.cpp.
LarryChen
July 12th, 2005, 06:36 PM
Thanks so much for your sample code. I tried to use your methology in my code but still it didn't work. It looked like the reading thread is always stucked, which means the writing thread is not able to reset reading event and so the reading thread is always blocked. I have attached my code. Please help me! I am a multithreading newbie!
Larry, you need to pass the event handles to each of your thread procedures. Plus you need to wait for the events in each thread proc, and set each event so the opposite thread wakes up appropriately.
I've attached a sample app, which simulates the reading and writing to a file. Although it doesn't actually perform any file reading or writing, it does keep track of a file read/write positions. So it should be somewhat simple to convert to real file operations.
Be warned that this code has been written in more of a C++ style where the thread procs are static members of a class. I chose this method because it makes things much easier to pass data around between threads.
P.S. I wrote this in VC7.1 so if you are using an earlier compiler just copy the code out of AltThreads.cpp.
Arjay
July 12th, 2005, 07:13 PM
Thanks so much for your sample code. I tried to use your methology in my code but still it didn't work. It looked like the reading thread is always stucked, which means the writing thread is not able to reset reading event and so the reading thread is always blocked. I have attached my code. Please help me! I am a multithreading newbie!While it seems that you are writing in small chunks, it doesn't look like you are reading in small chunks.
Are you sure this code only reads for a certain number of bytes before allowing T1 to run? It seems that it always reads to the end of the file. Is this what you want?
Thanks for your reply! The function fgets reads characters from the current stream position to and including the first newline character. So it always reads one line every time. Is anything wrong?
While it seems that you are writing in small chunks, it doesn't look like you are reading in small chunks.
Are you sure this code only reads for a certain number of bytes before allowing T1 to run? It seems that it always reads to the end of the file. Is this what you want?