help: weird behaviour of sem_getvalue
Ross Johnson
rpj@callisto.canberra.edu.au
Tue Dec 9 13:56:00 GMT 2003
Hi Shantanu,
The sem_getvalue.c file contains the following comments:-
/*
* There appears to be NO atomic means of determining the
* value of the semaphore. Using only ReleaseSemaphore()
* with either a zero or oversized count parameter has been
* suggested but this trick doesn't produce consistent results
* across Windows versions (the technique uses values that are
* knowingly illegal but hopes to extract the current value
* anyway - the zero parameter appears to work for Win9x but
* neither work reliably for WinNT).
*
* The intrusive method below will give false results
* at times but it at least errs on the side of
* caution. Competing threads might occasionally believe
* the semaphore has a count of one less than it actually
* would have and possibly block momentarily unecessarily,
* but they will never see a higher semaphore value than
* there should be.
*
*
* Multiple threads calling sem_getvalue() at the same time
* may not all return the same value (assuming no calls to
* other semaphore routines). They will always return the
* correct value or a lesser value. This problem could be fixed
* with a global or a per-semaphore critical section here.
*
* An equally approximate but IMO slightly riskier approach
* would be to keep a separate per-semaphore counter and
* decrement/increment it inside of sem_wait() and sem_post()
* etc using the Interlocked* functions.
*/
The method used performs a WaitForSingleObject() call on the (underlying
Win32) semaphore with a 0 timeout. If it returns WAIT_TIMEOUT then the
semaphore was 0, otherwise it immediately releases the sema and gets the
(value-1) through ReleaseSemaphore().
Wrapping all this in a critical section would add overhead to every
other sem_*() call.
Regards.
Ross
Shantanu Gogate wrote:
>Hi,
>I am using pthreads-win32 package( was using pthreads-win32-2003-05-10.exe and also tried the
>latest 2003-09-18.exe) but facing a weird problem using sem_getvalue. I have replicated what I am
>trying to do thru this snippet of code which you can test for yourself. Basically there is a
>semaphore which is set to one before the threads are launched. one or more threads continuously
>check the value of this semaphore to see if it has become zero and if it has, then the thread
>exits. Interestingly if you comment out the pthread_exit line then you that the sem_getvalue
>returns the value of semaphore as zero for a brief period of time and then starts reporting it as
>one again !! if i compile the same code on a linux box this anomaly is not observed. Is this is a
>bug in win32-pthreads ? Any help would be appreciated.
>
>Shantanu Gogate.
>
>the code:
>
><<<<
>#include <pthread.h>
>#include <semaphore.h>
>#include <stdio.h>
>
>static sem_t g_sem_ready,g_sem_queue;
>
>void *consumer(void *args) {
> int count=0,value;
> while(1) {
> sem_getvalue(&g_sem_ready,&value);
> printf("consumer ready= %d\n",value);
> if(value <= 0 ) {
> sem_getvalue(&g_sem_queue,&value);
> // printf("consumer exiting, with %d pending\n", value);
> pthread_exit(0);
> }
> else {
> sem_wait(&g_sem_queue);
> count++;
> // printf("consumed %d\n",count);
> }
> }
>}
>
>void *producer(void *args) {
> int value,count=0;
> while(1) {
> sem_getvalue(&g_sem_ready,&value);
> printf("producer ready= %d\n",value);
> if(value <= 0 ) {
> printf("producer exiting\n");
> // pthread_exit(0);
> }
> else {
> count++;
> // printf("produced %d\n",count);
> sem_post(&g_sem_queue);
> if(count > 200)
> pthread_exit(0);
> }
> }
>}
>int main(int argc, char *argv[]) {
> pthread_t th1, th2;
> int status;
>
> sem_init(&g_sem_ready,0,0);
> sem_init(&g_sem_queue,0,0);
>
> sem_post(&g_sem_ready);
> pthread_create(&th1,NULL, consumer, NULL);
> pthread_create(&th2,NULL, producer, NULL);
> sleep(10);
> printf("going down baby\n");
> sem_wait(&g_sem_ready);
> pthread_join(th2,(void **)&status);
> pthread_join(th1,(void **)&status);
>}
>
>
>
>
>
>
>__________________________________
>Do you Yahoo!?
>Protect your identity with Yahoo! Mail AddressGuard
>http://antispam.yahoo.com/whatsnewfree
>
>
More information about the Pthreads-win32
mailing list