Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

CMutex Question

Status
Not open for further replies.

chr123

Technical User
Feb 9, 2005
3
DE
The question is simple: Why doesn't show up a message box? The operation ("do") startet in MyControllingFunction is lengthy. So all new threads are started in parallel. The mutexes are created in different threads, but should all refer to the same kernel object.

What point am I missing?

Thank's for any help. Christian

---------
UINT MyControllingFunction(LPVOID pParam )
{
CMyObject* pObject = (CMyObject*)pParam;

// Ensure exclusive execution
CMutex *oMttx = new CMutex(FALSE, "MUTEST");
CSingleLock singleLock(oMttx, FALSE);
if(singleLock.IsLocked()==TRUE){
AfxMessageBox("already in process!", MB_OK,0);
return 0;
}
else{
singleLock.Lock();
}

if (pObject == NULL ||
!pObject->IsKindOf(RUNTIME_CLASS(CMyObject)))
return 1; // if pObject is not valid

pObject->do();

return 0; // thread completed successfully
}

void CFormXYZ::OnBnClickedButton1()
{
CWinThread *cwt = AfxBeginThread(MyControllingFunction, &myObject);
cwt = AfxBeginThread(MyControllingFunction, &myObject);
cwt = AfxBeginThread(MyControllingFunction, &myObject);
cwt = AfxBeginThread(MyControllingFunction, &myObject);
cwt = AfxBeginThread(MyControllingFunction, &myObject);
}
 
Ok, got it! The trick is to switch the statements (more or less):

// Ensure exclusive execution
CMutex *oMttx = new CMutex(FALSE, "MUTEST");
CSingleLock singleLock(oMttx, FALSE);
singleLock.Lock(10); // The 10 is important, otherwise this statements blocks the execution, until you can acquire a lock.

if(singleLock.IsLocked()==FALSE){
AfxMessageBox("Could not get lock!", MB_OK,0);
return 0;
}
 
Glad you found it, but perhaps I could clarify a bit more.

IsLocked only returns TRUE if you've managed to get a lock in the current CSingleLock instance, it will return FALSE if you haven't even tried to take the lock (even though another CSingleLock infact has locked it).
You rarely need to call IsLocked, use the return of Lock directly.

Ie
Code:
   if(!singleLock.Lock(10)){
        AfxMessageBox("Could not get lock!", MB_OK,0);
        return 0;
    }

>The 10 is important, otherwise this statements blocks the execution

Actually it just waits for the other thread to realease the lock, with no param you just wait forever.

A minor note:
Code:
  something == TRUE
comparisons aren't all that good because in C/C++ everything !=0 is regarded as true not just whetever value TRUE is defined to be.

/Per

www.perfnurt.se
 
Oh, and another thing. Do you really just want to wait 10 milliseconds? The purpose of the whole synching is just to make sure one thread access <whatever> at the time. It is seldom bug-out-if-I-wait-too-long.

Ie try
Code:
UINT MyThreadFunc(LPVOID pParam )
{
	int i = (int) pParam;
    CMutex mutex(FALSE, "MUTEST");

	while(true)
	{
		CSingleLock singleLock(&mutex, TRUE);        
		{
			cout << "[" << i;
			cout << i << "]";
		}
    }

    return 0;   
}
 ...
	AfxBeginThread(MyThreadFunc,(LPVOID) 1);
	AfxBeginThread(MyThreadFunc,(LPVOID) 2);
	AfxBeginThread(MyThreadFunc,(LPVOID) 3);
	AfxBeginThread(MyThreadFunc,(LPVOID) 4);
	AfxBeginThread(MyThreadFunc,(LPVOID) 5);

	while(true)
	{
	}
Which synch cout access and the output is nice and tidy. Compare result with execution where the CSingleLock line is commented out.

/Per

www.perfnurt.se
 
>>The 10 is important, otherwise this statements blocks the execution

>Actually it just waits for the other thread to realease the lock, with no param you just wait forever.

That is correct. If you block forever, the next lines of code wouldn't make any sense.

>Oh, and another thing. Do you really just want to wait 10 milliseconds?

I just want to check if one task is currently executed, that is all. So I try to get a lock on it. This is perhaps a little overkill for such a task, but I wanted to try this synchronizing stuff.

>>something == TRUE
>comparisons aren't all that good because in C/C++ everything !=0 is regarded as true not just whetever value TRUE is defined to be.

I did not get the point, here. The return value of the singleLock.IsLocked() function is defined as BOOL (TRUE or FALSE). Why shouldn't I check for this value?
 
>The return value of the singleLock.IsLocked() function is defined as BOOL

Well, if you look into MSDN it actually says:

Return Value

Nonzero if the object is locked; otherwise 0.

It prolly works fine for your case here, but in general it's good to avoid == TRUE (or ==true) comparisons, for the reason I just mentioned. As a side bonus you then never have to think about if it's bool, BOOL, int, pointer or whatever. No big deal though, it's just a suggestion (feel free to ignore it...)

/Per

www.perfnurt.se
 
By the way, if you look into windef.h you'll see
Code:
typedef int BOOL;

No TRUE/FALSE restrictions here...


/Per

www.perfnurt.se
 
That's why I avoid all Windows types like the plague...
BOOL, DWORD, CHAR... Why does anyone use them?
Just use bool, long, char...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top