|
|
|||||||||
|
|||||||||
| |||||||||
|
|
|
| |||||||||
![]() |
|
|
«
Previous Thread
|
Next Thread
»
|
Thread Tools | Search this Thread | Rate Thread | Display Modes |
|
#1
|
|||
|
|||
|
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
|
||||
|
||||
|
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);
}
}
|
|
#3
|
||||
|
||||
|
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);
}
|
|
#4
|
|||
|
|||
|
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? |
|
#5
|
||||
|
||||
|
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. |
|
#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. |
|
#7
|
||||
|
||||
|
ok i will zip them up and post them here. do you need them right now?
|
|
#8
|
|||
|
|||
|
Whenever you get a chance...
|
|
#9
|
||||
|
||||
|
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
![]() |
|
#10
|
|||
|
|||
|
Thanks ill have a look
|
|
#11
|
|||
|
|||
|
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 |
|
#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? |
|
#13
|
|||
|
|||
|
|
|
#14
|
|||
|
|||
|
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?
|
|
#15
|
||||
|