Monday, May 23, 2016

Digest for comp.programming.threads@googlegroups.com - 2 updates in 1 topic

Bonita Montero <Bonita.Montero@gmail.com>: May 22 07:19PM +0200

I've written a very efficient condvar-implementation for Win32.
Here it is: http://pastebin.com/fdjHx9ec
I'm pretty sure it's considerably more efficient than the
condvars in Win32 since Vista and Windows Server 2008.
 
But I had a strange phnomenon when a thread holding the condvar
locked is singalling a waiting thread and after this is sleeping
before it is releasing the lock.
I extracted the problem in a simple programm without this kind
of efficient locking through atomic variables, but just with an
event and a semaphore. Here it is:
 
#include <windows.h>
#include <stdio.h>
 
HANDLE hEvt,
hSema;
bool volatile fReleased = false;
 
DWORD WINAPI LockAndReleaseThread( LPVOID lpvThreadParam );
 
int main()
{
int const NTHREADS = 2;
HANDLE ahWait[2];
 
ahWait[0] = ::hEvt = CreateEvent( NULL, FALSE, TRUE, NULL );
ahWait[1] = ::hSema = CreateSemaphore( NULL, 0, 1, NULL );
 
for( int i = 0; i < NTHREADS; i++ )
CreateThread( NULL, 0, LockAndReleaseThread, NULL, 0, NULL );
 
for( ; ; )
{
WaitForMultipleObjects( 2, ahWait, TRUE, INFINITE );
printf( "main thread is holding lock and received signal\n" );
::fReleased = false;
SetEvent( hEvt );
}
 
return 0;
}
 
DWORD WINAPI LockAndReleaseThread( LPVOID lpvThreadParam )
{
for( ; ; )
{
WaitForSingleObject( hEvt, INFINITE );
printf( "spawned thread is holding lock\n" );
 
if( !::fReleased )
ReleaseSemaphore( ::hSema, 1, NULL ),
::fReleased = true;
 
Sleep( 1000 );
SetEvent( hEvt );
}
 
return 0;
}
 
The strange thing here is, that whith my Windows 10 computer,
WaitForMultipleObjects in the main-thread never awakens!
When I set NTHREADS to 1, the main-thread gets a chance, but
beyond it will freeze.
Has anyone an explanation for that?
 
Thanks in advance,
Bonita Montero
 
--
http://facebook.com/bonita.montero/
 
---
Diese E-Mail wurde von Avast Antivirus-Software auf Viren geprüft.
https://www.avast.com/antivirus
Bonita Montero <Bonita.Montero@gmail.com>: May 23 12:55PM +0200

I've got a solution for this problem.
In the main-thread, simply wait for the semaphore and then for the
event (in this order - or you're gonna deadlock) with WaitForSingle
Object. That's not so efficitent, but works.
 
int main()
{
int const NTHREADS = 2;
HANDLE ahWait[2];
 
::hEvt = CreateEvent( NULL, FALSE, TRUE, NULL );
::hSema = CreateSemaphore( NULL, 0, 1, NULL );
fReleased = false;
 
for( int i = 0; i < NTHREADS; i++ )
CreateThread( NULL, 0, LockAndReleaseThread, NULL, 0, NULL );
 
for( ; ; )
WaitForSingleObject( ::hSema, INFINITE ),
WaitForSingleObject( ::hEvt, INFINITE),
printf( "main thread is holding lock and received signal\n" ),
::fReleased = false,
SetEvent( ::hEvt );
 
return 0;
}
 
 
--
http://facebook.com/bonita.montero/
 
---
Diese E-Mail wurde von Avast Antivirus-Software auf Viren geprüft.
https://www.avast.com/antivirus
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.programming.threads+unsubscribe@googlegroups.com.

No comments: