-
Multi-Thread Programming
This is a plain simple question. I'm using Borland C++ v4.52. How do you multi-thread programs so that 2 seperate parts are syncronised? And it helps alot if applied in source code so if you could give an example, that would be really helpful. Thanks, Dr. Droid.
-
You question is not as simple as you imagine.
I know nothing about Borland documentation. However, go to http://msdn.microsoft.com/library/default.asp and enter "Writing a Multithreaded Win32 Program" in the search engine and read up on the topic complements of MSDN.
hth
-
You need a compiler that will compiler Windows programs (I am not familiar with your compiler so I dont know....but the Borland Builder compilers will do it)....
You need to look at the Win32 Function CreateThread().......but beware that this func can occasionally have problems when linked along with any of the standard libraries........you would do well to try use straight win32 funtions in your program when using this function. Alternatively, your compiler should offer a "safer" function that can be used allong with the std libs......in MSVC this function would be _beginthreadex()....but I dont know the equivilent Borland func.....
As to syncronisation this would depend on what you want to do.....if you want to control execution speed, then perhaps thread priorities are what you want...but these themselves can cause trouble with other applications.......
If you want to syncronise access to data, then perhaps critical sections will help......these are easy to inplement and ensure that variables that are accessed at the same time by more than 1 thread can be accessed safely without 1 thread messing up the tasks of the other..............there are more complex sync methods, but it depends on what you intend to do.
-
Examples?
Do you have any examples (source code) of how to do this?
-
I could do an example, but what exactly do you want to do?
-
Syncronise
I want to create a program that syncronises data...
-
I am assuming that you mean syncronising access to data where threads could read manipulate and replace data without the threat of another thread changing it before it has finished manipulating.....
Ok....I think I managed an example, but I admit I fount it hard to show a simple example where thread sync was needed........therefore I may have gone over the top to prove a point
Anyway......I wrote a program that fills a buffer with the 26 letter of the alphabet......it the shows that buffer in a message box.......the buffer is filled by 2 threads working at exactly the same time doing the same thing.......now....the program needs to ensure that while 1 thread is filling 1 member of the array the other thread does not do anything to cause the first threads efforts to be spoiled...
With critical sections.....when 1 thread has access to data, it is guaranteed that another thread cannot manipulate it.........if a second thread tries to access that variable, then the second thread is put to sleep until the first thread has done what it wanted...the second thread is then preempted and is allowed to do what it wants........
Code:
#include <windows.h>
int nIncrement = 0; //increment thats used by both threads
bool bThread1 = false,//A little test to see if both threads..
bThread2 = false;//..recieved CPU time
char buffer[27];//Buffer to fill with alphabet
CRITICAL_SECTION cs;//Critical section that syncs threads
DWORD WINAPI ThreadProc1(void){
bool bLoop = true;
char cAlpha;
while(bLoop){
EnterCriticalSection(&cs);
/*Add capital letter to buffer*/
cAlpha = nIncrement+65;
Sleep(20);//To stall thread execution
buffer[nIncrement] = cAlpha;
Sleep(20);//To stall thread execution
nIncrement++;//Increment counter
bThread1 = true;//To show that this thread was used
if(nIncrement>=25)bLoop = false;//is the buffer full?
LeaveCriticalSection(&cs);
}
return 0;
}
DWORD WINAPI ThreadProc2(void){
bool bLoop = true;
char cAlpha;
while(bLoop){
EnterCriticalSection(&cs);
/*Add capital letter to buffer*/
cAlpha = nIncrement+65;
Sleep(20);//To stall thread execution
buffer[nIncrement] = cAlpha;
Sleep(20);//To stall thread execution
nIncrement++;//Increment counter
bThread2 = true;//To show that this thread was used
if(nIncrement>=25)bLoop = false;//is the buffer full?
LeaveCriticalSection(&cs);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance,
LPSTR lpszArgument, int nFunsterStil)
{
DWORD dwThread1,dwThread2;//Thread ID's (not used)
HANDLE hThreads[2];//Thread handles
InitializeCriticalSection(&cs);//Setup the Critical Section
hThreads[0] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE )
ThreadProc1,NULL,0,&dwThread1);//Start thread 1
hThreads[1] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE )
ThreadProc2,NULL,0,&dwThread2);//Start thread 2
/*Hold execution until threads have finished*/
WaitForMultipleObjects(2,hThreads,TRUE,INFINITE);
DeleteCriticalSection(&cs);//Cleanup
buffer[27] = NULL;//Null the end of the buffer
MessageBox(HWND_DESKTOP,buffer,"Results",MB_OK);//Display
/*Test to show that each thread recieved CPU time
and did affect the buffer*/
if(bThread1)
MessageBox(HWND_DESKTOP,"Thread 1 was used","",MB_OK);
if(bThread2)
MessageBox(HWND_DESKTOP,"Thread 2 was used","",MB_OK);
return 0;
}
Now this should do as it was meant to do....but if you comment the EnterCriticalSection() and the LeaveCriticalSection() in each thread procedure then you may find the program will not do as it should..(On mine, the first thread put 'A' in the buffer and that's all)...but if you uncomment the funcs again it will work....
I admit I probably went overboard with the Sleep()s....but it helped prove the point in a short program....sorry if this is not as good or as clear an example as it could be....its just that its not an easy method to give an example of.