From: Ross Johnson <rpj@callisto.canberra.edu.au>
To: Shantanu Gogate <sagogate@yahoo.com>, pthreads-win32@sources.redhat.com
Subject: Re: help: weird behaviour of sem_getvalue
Date: Tue, 09 Dec 2003 13:56:00 -0000 [thread overview]
Message-ID: <3FD5D4BD.1070205@callisto.canberra.edu.au> (raw)
In-Reply-To: <20031209063011.31491.qmail@web60710.mail.yahoo.com>
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
>
>
next parent reply other threads:[~2003-12-09 13:56 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20031209063011.31491.qmail@web60710.mail.yahoo.com>
2003-12-09 13:56 ` Ross Johnson [this message]
2003-12-08 7:59 Shantanu Gogate
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3FD5D4BD.1070205@callisto.canberra.edu.au \
--to=rpj@callisto.canberra.edu.au \
--cc=pthreads-win32@sources.redhat.com \
--cc=sagogate@yahoo.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).