Page 1 of 2 12 Last
  • Jump to page:
    #1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2003
    Posts
    79
    Rep Power
    12

    Mutex driving me insane.....


    A few weeks ago I posted a question about interthreadcommunication. I was given a very good explination of the theory and even what to use to do it. The suggestion was "mutex". Now I have found about three tutorials on it but they arent complete or cryptic. I have spent the last 2 weeks trying to work it out. It just isnt happening.

    What I want to do is simply lock a variable while one threads accessing it so another cant.

    If anyone has a little simple snippet of code that illistrates how to do this it would help me so much....

    Thanks in advance....
  2. #2
  3. not a fan of fascism (n00b)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Feb 2003
    Location
    ct
    Posts
    2,756
    Rep Power
    95
    u didnt say what OS your using so...here is a simplistic example. this is assuming you are using win32 thread functions and that there exists a global variable count.
    Code:
    void count_thread(int iterations)
    {
         int i, x;
         for(i=0; i<iterations; i++)
         {
             // wait until the mutex is free before incrementing
             WaitForSingleObject(mutex, INFINITE);  
              x = count;
              x++;
              count = x;
              // free the mutex for other threads
              ReleaseMutex(mutex);
           }
    }
  4. #3
  5. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,143
    Rep Power
    2222
    The idea is that both threads sharing the resource use the same mutex and that you lock the mutex before using the shared resource and unlock it when you are done. Of course, the mutex must be initialized before you can use it and destroyed when you are completely done with it.

    An example in pthreads under Linux:
    Code:
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <pthread.h>
    #include <semaphore.h>
    
    void *thread_function(void *arg);
    pthread_mutex_t work_mutex; /* protect work_area and time_to_exit */
    #define WORK_SIZE 1024
    char work_area[WORK_SIZE];
    int time_to_exit = 0;
    
    int main() {
        int res;
        pthread_t a_thread;
        void *thread_result;
        res = pthread_mutex_init(&work_mutex, NULL);
        if (res != 0) {
            perror("Mutex initialization failed");
            exit(EXIT_FAILURE);
        }
        res = pthread_create(&a_thread, NULL, thread_function, NULL);
        if (res != 0) {
            perror("Thread creation failed");
            exit(EXIT_FAILURE);
        }
        pthread_mutex_lock(&work_mutex);
        printf("Input some text. Enter 'end' to finish\n");
        while(!time_to_exit) {
            fgets(work_area, WORK_SIZE, stdin);
            pthread_mutex_unlock(&work_mutex);
            while(1) {
                pthread_mutex_lock(&work_mutex);
                if (work_area[0] != '\0') {
                    pthread_mutex_unlock(&work_mutex);
                    sleep(1);
                }
                else {
                    break;
                }
            }
        }
        pthread_mutex_unlock(&work_mutex);
        printf("\nWaiting for thread to finish...\n");
        res = pthread_join(a_thread, &thread_result);
        if (res != 0) {
            perror("Thread join failed");
            exit(EXIT_FAILURE);
        }
        printf("Thread joined\n");
        pthread_mutex_destroy(&work_mutex);
        exit(EXIT_SUCCESS);
    }
    
    void *thread_function(void *arg) {
        sleep(1);
        pthread_mutex_lock(&work_mutex);
        while(strncmp("end", work_area, 3) != 0) {
            printf("You input %d characters\n", strlen(work_area) -1);
            work_area[0] = '\0';
            pthread_mutex_unlock(&work_mutex);
            sleep(1);
            pthread_mutex_lock(&work_mutex);
            while (work_area[0] == '\0' ) {
                pthread_mutex_unlock(&work_mutex);
                sleep(1);
                pthread_mutex_lock(&work_mutex);
            }
        }
        time_to_exit = 1;
        work_area[0] = '\0';
        pthread_mutex_unlock(&work_mutex);
        pthread_exit(0);
    }
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2003
    Posts
    79
    Rep Power
    12
    Thanks for that. I am using windows 32. Now here is where I get confused.

    This is the code you posted. Ill explain the stuff thats giving me a hard time.


    Code:
    void count_thread(int iterations)
    {
         int i, x;
         for(i=0; i<iterations; i++)
         {
             // wait until the mutex is free before incrementing
             WaitForSingleObject(mutex, INFINITE);  
              x = count;
              x++;
              count = x;
              // free the mutex for other threads
              ReleaseMutex(mutex);
           }
    }
    This is the line that I dont get:

    Code:
    WaitForSingleObject(mutex, INFINITE);
    I understand what is happening, You are telling the thread to wait untill the "mutex" is free and the wait time is infinite. But what varaible is the mutex?

    For example if I had a variable called "char *buf[100]" and there are two threads trying to read and write to buff simutaniously. I would want to lock "buf" while I was reading so the other thread cant change the value in the middle of it.

    How would I do that?
    Does this define buf as the variable to be locked?

    Code:
    Char *buf[100]
    WaitForSingleObject(buf, INFINITE);
    Can you explain this too me?
  8. #5
  9. not a fan of fascism (n00b)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Feb 2003
    Location
    ct
    Posts
    2,756
    Rep Power
    95
    ok i get what your saying now. from my understanding, the mutex doesn't actually "protect" the variable itself, rather it protects an area of code that uses that variable. one thing that confuses me is the difference between a Mutex and a CriticalSection, as they both seem to accomplish the same goal. but anyways, in your above code, i dont think what you have would work, something like this would:
    Code:
    // wait until the mutex is free before reading/writing
    WaitForSingleObject(mutex, INFINITE);  
    //perform read or write
    // free the mutex for other threads
    ReleaseMutex(mutex);
    if your dealing with the read/write problem, there are also other factors to take into consideration. Race conditions, Deadlocks; you should google both of those terms b/c they are very important to keep in mind. You also may want to google semaphore, as that is a good solution to your problem. becuase surely it will be alright for multiple threads to read from teh same buffer, but with a mutex i dont think you can accomplish this. a semaphore will allow you to do this much easier. If you would like, i could send you some of the code examples from my Win32 book, there are extensive examples of what im speaking of.

    edit: answered my own question:

    Mutex

    Similar to a Critical Section with two differences.

    It can cross process boundaries.

    Can be given a string name

    Also Mutexís donít have a class wrapper like a Critical Section.
    Last edited by infamous41md; June 1st, 2003 at 07:54 PM.
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2003
    Posts
    79
    Rep Power
    12
    Examples would be great. I have read up on all the topics you have mentioned but I have the same problem with them all. I just cant get my head arround what the hell I am actually locking and how I specify whats being locked.

    So any examples would help. If I can just figure this bit out the rest of my project will run so much smoother.
  12. #7
  13. not a fan of fascism (n00b)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Feb 2003
    Location
    ct
    Posts
    2,756
    Rep Power
    95
    ok i will zip them up and post them here. do you need them right now?
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2003
    Posts
    79
    Rep Power
    12
    Whenever you get a chance...
  16. #9
  17. not a fan of fascism (n00b)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Feb 2003
    Location
    ct
    Posts
    2,756
    Rep Power
    95
    here u go. it's a tar file, if u cant open it, tell me and i'll switch over to XP and zip it up :)
    Attached Files
  18. #10
  19. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2003
    Posts
    79
    Rep Power
    12
    Thanks ill have a look
  20. #11
  21. No Profile Picture
    Offensive Member
    Devshed Novice (500 - 999 posts)

    Join Date
    Oct 2002
    Location
    in the perfect world
    Posts
    622
    Rep Power
    27
    You must create a mutex handle for the section to be 'locked'.....

    then release it when the thread has finished (to allow the other thread access).

    Code:
    HANDLE    mutex=NULL;
    
    mutex = CreateMutex(NULL,  //no security
                   FALSE, //no owner
                    szMutexName); // the handles name
    The essence of Christianity is told us in the Garden of Eden history. The fruit that was forbidden was on the Tree of Knowledge. The subtext is, All the suffering you have is because you wanted to find out what was going on. You could be in the Garden of Eden if you had just kept your f***ing mouth shut and hadn't asked any questions.

    Frank Zappa
  22. #12
  23. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2003
    Posts
    79
    Rep Power
    12
    See that still confuses me..... I still dont get what variable is the mutex...

    For example:

    Code:
    #include <windows.h>
    #include <iostream.h> 
    
    #define MAX_THREADS 2
    char buf[100]="empty";
    
    HANDLE hThreads[MAX_THREADS];	// An array of thread handles.
    
    DWORD  id[MAX_THREADS];	// An array of thread id's.
    
    
    int c = 1;
    int j = 1;
    
    DWORD WINAPI ReadThread(LPVOID n) {
    
    	while(j<10)
    	{
    
    cout<<"thread1 ";	
    cout<<buf;
    cout<<"\n";
    
    }
    	return (DWORD)n;
    }
    
    DWORD WINAPI NetThread(LPVOID n) {
         while(c<10)
    {
    int PORT=3550;     	      	
    int MAXDATASIZE=1000;      	    
    
    
    
    struct       sockaddr_in server;   
                 SOCKADDR_IN addr,			
                 remote_addr;		
    int iRemoteAddrLen;	
    
    
    
    
    WSADATA  wsdata;
    SOCKET   sock;
    DWORD    wsock;
    
    
    
    	WSAStartup(0x0202,&wsdata);	
      if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)      	
       {
            MessageBox(0,"call socket failed","Error",0);
             return -1;
       }
    
    		addr.sin_family = AF_INET;
    		addr.sin_port = htons(PORT);
    		addr.sin_addr.s_addr = INADDR_ANY;       
    		if(bind(sock, (struct sockaddr *) &addr, sizeof(addr)) == SOCKET_ERROR)
       {
     MessageBox(0,"Bind Socket Failed","Error",0);
             return -1;
       }
    
    	
    	iRemoteAddrLen = sizeof(remote_addr);
    if ((recvfrom(sock, buf, MAXDATASIZE, 0, (struct sockaddr *) &remote_addr, &iRemoteAddrLen))== -1)
    	
    	 {
               MessageBox(0," Recv Socket Error","Error",0);
             return -1;
       }
    
    
    closesocket(sock);     
     WSACleanup();
     
    	
    }
    return (DWORD)n;
    }
    
    
    int main(int argc, char* argv[]) {
    
    	int intParameter = 100;
    	char *string = "What's up?";
    
    	
    	hThreads[0] = CreateThread(NULL,0,ReadThread,(LPVOID)intParameter,NULL,&id[0]);
    	hThreads[1] = CreateThread(NULL,0,NetThread,(LPVOID)string,NULL,&id[1]);
    
    		WaitForMultipleObjects(MAX_THREADS,hThreads,TRUE,INFINITE);
    
    		for(int i = 0; i < MAX_THREADS; i++) {
    		CloseHandle(hThreads[i]);
    	}	
    
    	
    	return 0;
    }
    This is the most basic code I could put together to show where I am having trouble. Ignore anything else wrong with it. I just slapped it together for an example.

    Now in the code you will notice there are two threads. Both interact with a variable called "buf". One reads from "buf" and the other accepts a udp packet and writes the value to "buf". Now you can see the problem. If both threads access "buf" at the same time some very bad things can happen.

    How would one put a mutex on "buf"in this example?
  24. #13
  25. No Profile Picture
    Offensive Member
    Devshed Novice (500 - 999 posts)

    Join Date
    Oct 2002
    Location
    in the perfect world
    Posts
    622
    Rep Power
    27
    The essence of Christianity is told us in the Garden of Eden history. The fruit that was forbidden was on the Tree of Knowledge. The subtext is, All the suffering you have is because you wanted to find out what was going on. You could be in the Garden of Eden if you had just kept your f***ing mouth shut and hadn't asked any questions.

    Frank Zappa
  26. #14
  27. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2003
    Posts
    79
    Rep Power
    12
    yes...I have read it and several other papers. That document seems to show a mutex as more of a ticket to access a variable then a variable itself. What I still dont get though is how do you define which variable the mutex is locking?
  28. #15
  29. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,143
    Rep Power
    2222
    Originally posted by phantom_turtle
    yes...I have read it and several other papers. That document seems to show a mutex as more of a ticket to access a variable then a variable itself. What I still dont get though is how do you define which variable the mutex is locking?
    As the programmer, you know where in the code that variable is being accessed. That's the critical section! The mutex is a variable in its own right. What you do is that you lock the mutex right before a critical section and then you unlock it as soon as you leave the critical section. If the variable in question is accessed in more than one place, then you will have more than one critical section for that variable and you will use the same mutex for each of them.

    Now, if there is another variable that forms its own critical sections, you want to create another mutex for that variable and use it in those critical sections.

    The bottom line is that as the programmer you know where access to that variable needs to be controlled and that is where you use the mutex.

    And, yes, you can think of a mutex as "a ticket to access a variable". Or, if it would help, as that "Occupied" sign that appears on the door of an airliner toilet; when the "Occupied" sign appears, it is locked and your access is blocked until it is unlocked. Now that's a critical section!
    Last edited by dwise1_aol; June 3rd, 2003 at 11:56 PM.
Page 1 of 2 12 Last
  • Jump to page:

IMN logo majestic logo threadwatch logo seochat tools logo