Thread: multithreading...

  1. #1
    Registered User
    Join Date
    Apr 2004
    Posts
    210

    multithreading...

    I'm writing a multithreaded application. At the moment I use mutexes to protect data shared between threads. Everything works so far, but I believe I'm wasting quite a lot of CPU time in lockstates.

    The problem is that whenever I access a global variable, I have to lock it, even when I'm just going to read from it. If I would only lock on writes, multiple writes at the same time would be prevented, but I could still read during a write, which is just as bad.

    So I need some mechanism to lock data in a way that multiple reads can take place at the same time, but no two writes or reads and writes. I have come up with a sollution using three mutexes, but that pretty much looks like overkill.

    This whole thing sounds so much like a standard situation that I'm wondering why there is no standard sollution to it... or rather why I can't find it. Any links or suggestions are really welcome. Thanks

    This is my current code (using pthreads, but I wouldn't mind windows code either). It's giving preference to write attempts, preventing the start of more reads as soon as one thread tries to write.

    Code:
      #include <pthread.h>
      
      typedef struct {
        pthread_mutex_t tRead;
        pthread_mutex_t tWrite;
        pthread_mutex_t tInternal;
        int			 iRefCount;
      } TCritSect, *PCritSect;
      
      typedef enum {
        kCritSectRead,
        kCritSectWrite
      } ECritSectMode;
      
      
      void CritSectInit(PCritSect *ptCS) {
        pthread_mutex_init(&ptCS->tRead, NULL);
        pthread_mutex_init(&ptCS->tWrite, NULL);
        pthread_mutex_init(&ptCS->tInternal, NULL);
        ptCS->iRefCount= 0;
      }
      
      void CritSectDeinit(PCritSect *ptCS) {
        pthread_mutex_destroy(&ptCS->tRead);
        pthread_mutex_destroy(&ptCS->tWrite);
        pthread_mutex_destroy(&ptCS->tInternal);
      }
      
      void CritSectLock(PCritSect *ptCS, ECritSectMode eCSMode) {
        pthread_mutex_lock(&ptCS->tWrite);
      
        if (eCSMode == kCritSectRead) {
       	pthread_mutex_lock(&ptCS->tInternal);
      	if (ptCS->iRefCount == 0)
      	  pthread_mutex_lock(&ptCS->tRead);
    	iRefCount++;
      	pthread_mutex_unlock(&ptCS->tInternal);
     
      	pthread_mutex_unlock(&ptCS->tWrite);
      	return;
        }
        
        else {
      	pthread_mutex_lock(&ptCS->tRead);
      	return; // leave tWrite and tRead locked
        }
      }
      
      void CritSectUnlock(PCritSect *ptCS, ECritSectMode eCSMode) {
        if (eCSMode == kCritSectRead) {
      	pthread_mutex_lock(&ptCS->tInternal);
      	iRefCount--;
      	if (ptCS->iRefCount == 0)
      	  pthread_mutex_unlock(&ptCS->tRead);
      	pthread_mutex_unlock(&ptCS->tInternal);
        }
        
        else {
      	pthread_mutex_unlock(&ptCS->tWrite);
      	pthread_mutex_unlock(&ptCS->tRead);
        }
      }
    Last edited by Nyda; 09-02-2004 at 11:13 AM.

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    What you're looking for is a "read/write lock" which alot of pthread implementations do provide. Look in your documentation for pthread_rwlock_* API's.

    Google "reader writer lock" for more information on how to implement one yourself.

    gg

  3. #3
    Registered User
    Join Date
    Apr 2004
    Posts
    210
    Quote Originally Posted by Codeplug
    What you're looking for is a "read/write lock" which alot of pthread implementations do provide. Look in your documentation for pthread_rwlock_* API's.

    Google "reader writer lock" for more information on how to implement one yourself.

    gg
    Thanks, those keywords helped a lot. I was browsing through several references, including glibc's pthreads, but nowhere did they mention read/write locks. Really odd

    I wonder which is more lightweight, conditions or mutexes? The implementation I found uses two condition codes and one mutex which looks pretty much like the same overkill I produced...

  4. #4
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    It may seem like overkill, but coming up with a correct implementation of a readers/writer lock isn't as easy as it may seem at first. Creating a "fair" readers/writer lock is even more fun.

    >> I wonder which is more lightweight, conditions or mutexes?
    Well, that's not really a fair comparison since a condition variable requires the use of a mutex anyway.

    gg

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Multithreading (flag stopping a thread, ring buffer) volatile
    By ShwangShwing in forum C Programming
    Replies: 3
    Last Post: 05-19-2009, 07:27 AM
  2. multithreading in C++
    By manzoor in forum C++ Programming
    Replies: 19
    Last Post: 11-28-2008, 12:20 PM
  3. Question on Multithreading
    By ronan_40060 in forum C Programming
    Replies: 1
    Last Post: 08-23-2006, 07:58 AM
  4. Client/Server and Multithreading
    By osal in forum Windows Programming
    Replies: 2
    Last Post: 07-17-2004, 03:53 AM
  5. Multithreading
    By JaWiB in forum Game Programming
    Replies: 7
    Last Post: 08-24-2003, 09:28 PM