Thread: CreateSemaphore/ReleaseSemaphore

  1. #1
    Registered User
    Join Date
    Aug 2005
    Posts
    2

    CreateSemaphore/ReleaseSemaphore

    Hi,

    I'm using several semaphores (max val 1) for IPC:

    hnd = CreateSemaphore (NULL, 1, 1, "SEM-1");
    ....
    result = WaitForSingleObject(hnd, INFINITE);

    If a process is killed or stopped while it holds the semaphore (val=0), the semaphore is not incremented by Windows (process cleanup ?).

    Doesn't windows cleanup (increment semaphore by process' decrements) on process termination ?

    I'm using Windows XP, 2000, 2003 Server, each process is a "console Application" developed with VC++ 6.0.

    Each assistance is welcome and appreciated.

    Thanx a lot.
    Last edited by nrieger; 08-02-2005 at 08:08 AM.

  2. #2
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Welcome to the forums!

    If a process is killed or stopped while it holds the semaphore (val=0), the semaphore is not incremented by Windows (process cleanup ?).

    Doesn't windows cleanup (increment semaphore by process' decrements) on process termination ?
    No. Semaphores are cleaned up (equivalent to calling CloseHandle) but they are not incremented. This is one of the many reasons that using TerminateThread/TerminateProcess is a bad idea. Nix provides the SEM_UNDO flag so that semaphore operations can be reversed on process termination, but this is not without serious semantic problems which makes its value dubious:
    Usenet Thread: semop and SEM_UNDO

    When a process terminates, its set of associated semadj structures is used to undo the effect of all of the semaphore operations it performed with the SEM_UNDO flag. This raises a difficulty: if one (or more) of these semaphore adjustments would result in an attempt to decrease a semaphore's value below zero, what should an implementation do? One possible approach would be to block until all the semaphore adjustments could be performed. This is however undesirable since it could force process termination to block for arbitrarily long periods. Another possibility is that such semaphore adjustments could be ignored altogether (somewhat analogously to failing when IPC_NOWAIT is specified for a semaphore operation). Linux adopts a third approach: decreasing the semaphore value as far as possible (i.e., to zero) and allowing process termination to proceed immediately.
    Usenet Thread: Counting semaphore

    > - Does this kernel object adjusts reference count to reflect abandonment by
    > one of the processes

    No.

    Closing a handle and changing the reference count are two different things.

    You might imagine a situation where there is a system-wide semaphore that is waited on by 9 processes and set to its intial value by a 10th. The 10th process would have only one job - to set the initial count of the semaphore and exit, but the programmer is sloppy so CloseHandle will not be called before exit. The other 9 processes would then contend for access to the semaphore based on the initial value.

    So you can see that it would be conceptually inappropriate for the OS to adjust the reference count simply because the handle was not closed.

    Another way to look at it is to imagine that a process incremented a sempahore 560 times, decrements 100, increments, 50, and decrements 70. Should the OS know to knock off 440 on the semaphore when the process exits? What happens if, at the point of abnormal termination, the semaphore is zero because the other processes snarfed all the counts? Should the OS make the value -460?
    Since your semaphore only has a count of one, it seems that a mutex would be an ideal alternative. A mutex is owned by a single thread at any one time. If the owning thread terminates without calling ReleaseMutex, it is declared abandoned. The wait functions return a value to indicate this:
    Quote Originally Posted by MSDN
    WAIT_ABANDONED The specified object is a mutex object that was not released by the thread that owned the mutex object before the owning thread terminated. Ownership of the mutex object is granted to the calling thread, and the mutex is set to nonsignaled.
    Other alternatives are to monitor the other thread or process to check it it has terminated or to use a reasonable timeout when waiting on your semaphore.

    If you ask the same question on different forums, it is nice to link to the other places you have posted the question. This saves people from wasting time giving you the same answers on different forums and allows people searching to benefit from all the threads.

  3. #3
    Registered User
    Join Date
    Aug 2005
    Posts
    2

    Thanx

    Thanx a lot for your help.

    Sorry for posting in multiple forums without linking, will not happen again in future postings.

Popular pages Recent additions subscribe to a feed