The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.
|
 |
|
Dev Shed Forums
> Programming Languages
> C Programming
|
Mutex driving me insane.....
Discuss Mutex driving me insane..... in the C Programming forum on Dev Shed. Mutex driving me insane..... C programming forum discussing all C derivatives, including C#, C++, Object-C, and even plain old vanilla C. These languages are low level languages, and used on projects such as device drivers, compilers, and even whole computer operating systems.
|
|
 |
|
|
|
|
|

Dev Shed Forums Sponsor:
|
|
|

May 28th, 2003, 11:56 PM
|
|
Contributing User
|
|
Join Date: May 2003
Posts: 79
Time spent in forums: 2 h 14 m 21 sec
Reputation Power: 11
|
|
|
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....
|

May 29th, 2003, 12:34 AM
|
 |
not a fan of fascism (n00b)
|
|
Join Date: Feb 2003
Location: ct
|
|
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);
}
}
|

May 29th, 2003, 10:23 AM
|
 |
Contributing User
|
|
Join Date: Jan 2003
Location: USA
|
|
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);
}
|

June 1st, 2003, 06:06 PM
|
|
Contributing User
|
|
Join Date: May 2003
Posts: 79
Time spent in forums: 2 h 14 m 21 sec
Reputation Power: 11
|
|
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?
|

June 1st, 2003, 07:43 PM
|
 |
not a fan of fascism (n00b)
|
|
Join Date: Feb 2003
Location: ct
|
|
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.
|

June 1st, 2003, 07:53 PM
|
|
Contributing User
|
|
Join Date: May 2003
Posts: 79
Time spent in forums: 2 h 14 m 21 sec
Reputation Power: 11
|
|
|
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.
|

June 1st, 2003, 07:55 PM
|
 |
not a fan of fascism (n00b)
|
|
Join Date: Feb 2003
Location: ct
|
|
|
ok i will zip them up and post them here. do you need them right now?
|

June 1st, 2003, 07:56 PM
|
|
Contributing User
|
|
Join Date: May 2003
Posts: 79
Time spent in forums: 2 h 14 m 21 sec
Reputation Power: 11
|
|
|
Whenever you get a chance...
|

June 1st, 2003, 08:15 PM
|
 |
not a fan of fascism (n00b)
|
|
Join Date: Feb 2003
Location: ct
|
|
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 
|

June 1st, 2003, 08:39 PM
|
|
Contributing User
|
|
Join Date: May 2003
Posts: 79
Time spent in forums: 2 h 14 m 21 sec
Reputation Power: 11
|
|
|
Thanks ill have a look
|

June 3rd, 2003, 04:05 AM
|
|
Offensive Member
|
|
Join Date: Oct 2002
Location: in the perfect world
|
|
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
|

June 3rd, 2003, 08:24 PM
|
|
Contributing User
|
|
Join Date: May 2003
Posts: 79
Time spent in forums: 2 h 14 m 21 sec
Reputation Power: 11
|
|
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?
|

June 3rd, 2003, 09:46 PM
|
|
Offensive Member
|
|
Join Date: Oct 2002
Location: in the perfect world
|
|
|

June 3rd, 2003, 11:18 PM
|
|
Contributing User
|
|
Join Date: May 2003
Posts: 79
Time spent in forums: 2 h 14 m 21 sec
Reputation Power: 11
|
|
|
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?
|

June 3rd, 2003, 11:51 PM
|
 |
Contributing User
|
|
Join Date: Jan 2003
Location: USA
|
|
Quote: 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.
|
Developer Shed Advertisers and Affiliates
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Rate This Thread |
Linear Mode
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|