Thread: multi-thread and synchronization

  1. #1
    Registered User
    Join Date
    Sep 2009
    Posts
    14

    multi-thread and synchronization

    I have the question about synchronization after looking at some articles in the web.
    If I am using mutex for controlling the unique session resource, what will happen if there exists several thread which want to request the session resource which is in use? As I don't know how to put them in queue and how the first waiting get the session resource? It is mainly in coding sample as I want.

  2. #2
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    The whole point of a mutex is to handle the low-level details of the synchronization process (eg: the 'queueing' that you were referring to) for you. All you have to do is make sure that every access to the data structure is done through that mutex.

    Just keep in mind that mutexes are not a total synchronization solution - they can't prevent deadlocks/starvation/etc, for example. For that, there isn't a simple answer. I while back I worked on dependency-detection algorithm, but never quite completed it. That would be the general idea, though, if you were looking for a fool-proof solution...

  3. #3
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    Quote Originally Posted by rchiu5hk View Post
    I have the question about synchronization after looking at some articles in the web.
    If I am using mutex for controlling the unique session resource, what will happen if there exists several thread which want to request the session resource which is in use? As I don't know how to put them in queue and how the first waiting get the session resource? It is mainly in coding sample as I want.
    If two or more threads request the MUTEX object, only one of them gets it, the other thread(s) block until the MUTEX becomes available. When a thread releases a MUTEX object the thread scheduler wakes up the next waiting thread on that object and gives it control of the MUTEX. If a thread acquires the MUTEX and fails to release it, it can cause a deadlock on all other waiting threads.. There is no guarantee that the first thread to wait on the mutex will be the first to get it, but in general the kernel tries to be 'fair'. Meaning one thread wont usually get the mutex twice while another hasnt gotten it once.

    Code:
    #include <windows.h>
    #include <stdio.h>
    
    HANDLE Mutex;
    
    DWORD WINAPI ThreadFunc(LPVOID pThreadNum){
    	WaitForSingleObject(Mutex , INFINITE);
    
    	char myString[256];
    	sprintf(myString , "Thread #%d Got the MUTEX.\n\0" , *(DWORD*)pThreadNum);
    
    	int x = 0;
    	while(myString[x]){
    		printf("%c" , myString[x]);
    		Sleep(rand() % 100 + 100 + (100 * *(DWORD*)pThreadNum));
    		x++;
    		}
    
    	ReleaseMutex(Mutex);
    
    	return 0;
    	}
    
    DWORD WINAPI AsyncThreadFunc(LPVOID pThreadNum){
    	// WaitForSingleObject(Mutex , INFINITE);
    
    	char myString[256];
    	sprintf(myString , "Thread #%d Got the MUTEX.\n\0" , *(DWORD*)pThreadNum);
    
    	int x = 0;
    	while(myString[x]){
    		printf("%c" , myString[x]);
    		Sleep(rand() % 100 + 100 + (100 * *(DWORD*)pThreadNum));
    		x++;
    		}
    
    	//ReleaseMutex(Mutex);
    
    	return 0;
    	}
    
    int main(){
    	
    	DWORD ThreadId = 0;
    
    	Mutex = CreateMutex(NULL , FALSE , TEXT("MyMutex"));
    
    	DWORD ThreadNumber1 = 0;
    	HANDLE Thread1 = CreateThread(NULL , 0  , ThreadFunc , (LPVOID)&ThreadNumber1 , 0 , &ThreadId);
    	DWORD ThreadNumber2 = 1;
    	HANDLE Thread2 = CreateThread(NULL , 0  , ThreadFunc , (LPVOID)&ThreadNumber2 , 0 , &ThreadId);
    
    	WaitForSingleObject(Thread1 , INFINITE);
    	WaitForSingleObject(Thread2 , INFINITE);
    
    	ThreadNumber1 = 0;
    	Thread1 = CreateThread(NULL , 0  , AsyncThreadFunc , (LPVOID)&ThreadNumber1 , 0 , &ThreadId);
    	ThreadNumber2 = 1;
    	Thread2 = CreateThread(NULL , 0  , AsyncThreadFunc , (LPVOID)&ThreadNumber2 , 0 , &ThreadId);
    
    	WaitForSingleObject(Thread1 , INFINITE);
    	WaitForSingleObject(Thread2 , INFINITE);
    
    	return 0;
    	}
    Last edited by abachler; 09-16-2009 at 02:45 AM.

  4. #4
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    If a thread acquires the MUTEX and fails to release it, it can cause a deadlock on all other waiting threads.
    Well, that would more appropriately be a simple 'bug' in the program. A true deadlock occurs when, say, thread #1 holds a mutex on resource 'A' and requests object 'B', while at the same time thread #2 holds a mutex on resource 'B' and requests object 'A'. It doesn't have to be that direct, either - it could also happen if T#1 waits for T#2 which waits for T#3 which waits for T#4 which waits for T#1!

  5. #5
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    Quote Originally Posted by Sebastiani View Post
    Well, that would more appropriately be a simple 'bug' in the program. A true deadlock occurs when, say, thread #1 holds a mutex on resource 'A' and requests object 'B', while at the same time thread #2 holds a mutex on resource 'B' and requests object 'A'. It doesn't have to be that direct, either - it could also happen if T#1 waits for T#2 which waits for T#3 which waits for T#4 which waits for T#1!
    THAT is a bug, it usually occurs because someone didn't do their layout planning for the workflow.

    What usually happens is-
    Thread1 needs exclusive access to two resources, lets say the DISK and the NETWORK.
    Thread 2 needs exclusive access to the NETWORK DISK and an INTERNAL_DATA_STRUCTURE.
    Thread3 needs exclusive access to NETWORK and INTERNAL_DATA_STRUCTURE


    Thread1 acquires the mutex for teh DISK
    Thread2 acquires the mutex for the NETWORK

    Thread1 waits forever to acquire the NETWORK because Thread2 has it
    Thread2 acquires the mutex for the INTERNAL_DATA_STRUCTURE

    Thread2 waits forever to acquire the DISK because Thread1 has it

    Thread3 Waits forever to acquire INTERNAL_DATA_STRUCTURE because Thread2 has it


    The solution is that a thread must 'reset' if it cannot acquire all the resources it needs, and retry. Generally in cases of mutual dependency, it is bad form to use INFINITE as the wait period, shorter periods should be used and checks performed to determine if the thread has all the required resources. Using the granularity of the system timer as a base time, count the number of potential threads that would simultaneously access a mutex, have each thread wait the system timer resolution before resetting, and upon reset multiply by the timer resolution, and have each thread wait that period of time before attempting to reacquire the resources.

    Since MUTEX's are generally used for interprocess resource control, it may not be possible to determine the number of threads that will attempt to access the resource, so waiting a random time before reattempting to acquire will work in those cases.
    Last edited by abachler; 09-16-2009 at 11:34 AM.

  6. #6
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by abachler View Post
    THAT is a bug, it usually occurs because someone didn't do their layout planning for the workflow.
    Well, that's true.

    Quote Originally Posted by abachler
    The solution is that a thread must 'reset' if it cannot acquire all the resources it needs, and retry. Generally in cases of mutual dependency, it is bad form to use INFINITE as the wait period, shorter periods should be used and checks performed to determine if the thread has all the required resources. Using the granularity of the system timer as a base time, count the number of potential threads that would simultaneously access a mutex, have each thread wait the system timer resolution before resetting, and upon reset multiply by the timer resolution, and have each thread wait that period of time before attempting to reacquire the resources.

    Since MUTEX's are generally used for interprocess resource control, it may not be possible to determine the number of threads that will attempt to access the resource, so waiting a random time before reattempting to acquire will work in those cases.
    That's a good approach, though if you really want a simple solution to the problem, just use one mutex for all resources (of course this might not be efficient enough in some circumstances). But it does prevent deadlock, and depending on how the mutex is implemented, starvation as well (most modern implementations would probably pass that test, I think).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. thread synchronization
    By radeberger in forum C++ Programming
    Replies: 13
    Last Post: 03-29-2009, 10:21 AM
  2. thread synchronization
    By l2u in forum Windows Programming
    Replies: 2
    Last Post: 08-23-2006, 01:12 PM
  3. Thread Synchronization in Win32
    By passionate_guy in forum C Programming
    Replies: 0
    Last Post: 02-06-2006, 05:34 AM
  4. Thread Synchronization :: Win32 API vs. MFC
    By kuphryn in forum Windows Programming
    Replies: 2
    Last Post: 08-09-2002, 09:09 AM
  5. Thread Synchronization :: MFC
    By kuphryn in forum Windows Programming
    Replies: 0
    Last Post: 04-21-2002, 09:27 AM