C Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me
Go Back   Dev Shed ForumsProgramming LanguagesC Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old May 28th, 2003, 11:56 PM
phantom_turtle phantom_turtle is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: May 2003
Posts: 81 phantom_turtle User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 14 m 21 sec
Reputation Power: 6
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....

Reply With Quote
  #2  
Old May 29th, 2003, 12:34 AM
infamous41md's Avatar
infamous41md infamous41md is offline
not a fan of fascism (n00b)
Dev Shed Frequenter (2500 - 2999 posts)
 
Join Date: Feb 2003
Location: ct
Posts: 2,756 infamous41md User rank is Sergeant (500 - 2000 Reputation Level)infamous41md User rank is Sergeant (500 - 2000 Reputation Level)infamous41md User rank is Sergeant (500 - 2000 Reputation Level)infamous41md User rank is Sergeant (500 - 2000 Reputation Level)infamous41md User rank is Sergeant (500 - 2000 Reputation Level) 
Time spent in forums: 2 Days 11 h 4 m 29 sec
Reputation Power: 26
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);
       }
}

Reply With Quote
  #3  
Old May 29th, 2003, 10:23 AM
dwise1_aol's Avatar
dwise1_aol dwise1_aol is offline
Contributing User
Dev Shed Expert (3500 - 3999 posts)
 
Join Date: Jan 2003
Location: USA
Posts: 3,845 dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level) 
Time spent in forums: 1 Month 1 Day 13 h 26 m 37 sec
Reputation Power: 462
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);
}

Reply With Quote
  #4  
Old June 1st, 2003, 06:06 PM
phantom_turtle phantom_turtle is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: May 2003
Posts: 81 phantom_turtle User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 14 m 21 sec
Reputation Power: 6
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?

Reply With Quote
  #5  
Old June 1st, 2003, 07:43 PM
infamous41md's Avatar
infamous41md infamous41md is offline
not a fan of fascism (n00b)
Dev Shed Frequenter (2500 - 2999 posts)
 
Join Date: Feb 2003
Location: ct
Posts: 2,756 infamous41md User rank is Sergeant (500 - 2000 Reputation Level)infamous41md User rank is Sergeant (500 - 2000 Reputation Level)infamous41md User rank is Sergeant (500 - 2000 Reputation Level)infamous41md User rank is Sergeant (500 - 2000 Reputation Level)infamous41md User rank is Sergeant (500 - 2000 Reputation Level) 
Time spent in forums: 2 Days 11 h 4 m 29 sec
Reputation Power: 26
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.

Reply With Quote
  #6  
Old June 1st, 2003, 07:53 PM
phantom_turtle phantom_turtle is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: May 2003
Posts: 81 phantom_turtle User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 14 m 21 sec
Reputation Power: 6
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.

Reply With Quote
  #7  
Old June 1st, 2003, 07:55 PM
infamous41md's Avatar
infamous41md infamous41md is offline
not a fan of fascism (n00b)
Dev Shed Frequenter (2500 - 2999 posts)
 
Join Date: Feb 2003
Location: ct
Posts: 2,756 infamous41md User rank is Sergeant (500 - 2000 Reputation Level)infamous41md User rank is Sergeant (500 - 2000 Reputation Level)infamous41md User rank is Sergeant (500 - 2000 Reputation Level)infamous41md User rank is Sergeant (500 - 2000 Reputation Level)infamous41md User rank is Sergeant (500 - 2000 Reputation Level) 
Time spent in forums: 2 Days 11 h 4 m 29 sec
Reputation Power: 26
ok i will zip them up and post them here. do you need them right now?

Reply With Quote
  #8  
Old June 1st, 2003, 07:56 PM
phantom_turtle phantom_turtle is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: May 2003
Posts: 81 phantom_turtle User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 14 m 21 sec
Reputation Power: 6
Whenever you get a chance...

Reply With Quote
  #9  
Old June 1st, 2003, 08:15 PM
infamous41md's Avatar
infamous41md infamous41md is offline
not a fan of fascism (n00b)
Dev Shed Frequenter (2500 - 2999 posts)
 
Join Date: Feb 2003
Location: ct
Posts: 2,756 infamous41md User rank is Sergeant (500 - 2000 Reputation Level)infamous41md User rank is Sergeant (500 - 2000 Reputation Level)infamous41md User rank is Sergeant (500 - 2000 Reputation Level)infamous41md User rank is Sergeant (500 - 2000 Reputation Level)infamous41md User rank is Sergeant (500 - 2000 Reputation Level) 
Time spent in forums: 2 Days 11 h 4 m 29 sec
Reputation Power: 26
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
File Type: tar sync.tar (60.0 KB, 275 views)

Reply With Quote
  #10  
Old June 1st, 2003, 08:39 PM
phantom_turtle phantom_turtle is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: May 2003
Posts: 81 phantom_turtle User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 14 m 21 sec
Reputation Power: 6
Thanks ill have a look

Reply With Quote
  #11  
Old June 3rd, 2003, 04:05 AM
TechNoFear TechNoFear is offline
Offensive Member
Dev Shed Novice (500 - 999 posts)
 
Join Date: Oct 2002
Location: in the perfect world
Posts: 594 TechNoFear User rank is Sergeant (500 - 2000 Reputation Level)TechNoFear User rank is Sergeant (500 - 2000 Reputation Level)TechNoFear User rank is Sergeant (500 - 2000 Reputation Level)TechNoFear User rank is Sergeant (500 - 2000 Reputation Level)TechNoFear User rank is Sergeant (500 - 2000 Reputation Level) 
Time spent in forums: 2 Days 14 h 6 m 15 sec
Reputation Power: 21
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

Reply With Quote
  #12  
Old June 3rd, 2003, 08:24 PM
phantom_turtle phantom_turtle is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: May 2003
Posts: 81 phantom_turtle User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 14 m 21 sec
Reputation Power: 6
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?

Reply With Quote
  #13  
Old June 3rd, 2003, 09:46 PM
TechNoFear TechNoFear is offline
Offensive Member
Dev Shed Novice (500 - 999 posts)
 
Join Date: Oct 2002
Location: in the perfect world
Posts: 594 TechNoFear User rank is Sergeant (500 - 2000 Reputation Level)TechNoFear User rank is Sergeant (500 - 2000 Reputation Level)TechNoFear User rank is Sergeant (500 - 2000 Reputation Level)TechNoFear User rank is Sergeant (500 - 2000 Reputation Level)TechNoFear User rank is Sergeant (500 - 2000 Reputation Level) 
Time spent in forums: 2 Days 14 h 6 m 15 sec
Reputation Power: 21

Reply With Quote
  #14  
Old June 3rd, 2003, 11:18 PM
phantom_turtle phantom_turtle is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: May 2003
Posts: 81 phantom_turtle User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 14 m 21 sec
Reputation Power: 6
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?

Reply With Quote
  #15  
Old June 3rd, 2003, 11:51 PM
dwise1_aol's Avatar
dwise1_aol dwise1_aol is offline
Contributing User
Dev Shed Expert (3500 - 3999 posts)
 
Join Date: Jan 2003
Location: USA
Posts: 3,845 dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)