Waiting for mutiple objects - Unix

This is a discussion on Waiting for mutiple objects - Unix ; How do I wait for multiple object, for instance, array of mutexes? I am looking for UNIX (Solaris) equivalent of WaitForMultipleObjects on Windows. I need to wait for an array of mutexes or any other sync objects and have wait ...

+ Reply to Thread
Results 1 to 6 of 6

Thread: Waiting for mutiple objects

  1. Waiting for mutiple objects

    How do I wait for multiple object, for instance, array of mutexes? I
    am looking for UNIX (Solaris) equivalent of WaitForMultipleObjects on
    Windows. I need to wait for an array of mutexes or any other sync
    objects and have wait function return with the index of the object
    that has been signaled.

  2. Re: Waiting for mutiple objects

    On Aug 6, 8:23*am, Sasha wrote:

    > How do I wait for multiple object, for instance, array of mutexes? I
    > am looking for UNIX (Solaris) equivalent of WaitForMultipleObjects on
    > Windows. I need to wait for an array of mutexes or any other sync
    > objects and have wait function return with the index of the object
    > that has been signaled.


    This is inappropriate. Mutexes should only be used in situations where
    they are almost never held for any significant period of time. As
    such, there should be no point in a 'wait for one of many mutexes'
    function. (Just grab whichever one you want most. 99.999 times out of
    100 you'll just get it.)

    If you want this capability, you are doing something wrong.

    Now if you want some other kind of synchronization device that's
    appropriate to use in a case where they are not unlocked most of the
    time and only held briefly, you can certainly write one. The
    pthread_cond_* functions make this easy. For that, you can add a 'wait
    for multiple objects' function yourself.

    Perhaps the simplest way is to have each thread block on its own
    condition variable, protected by a single mutex which also protects a
    global linked-list of blocked threads. When you release object, you
    traverse the linked list and mark a particular thread as to be woken
    and then signal its condition variable. You can implement FIFO
    semantics if you want just by adding a thread at the end of the linked
    list and waking the first suitable thread.

    DS

  3. Re: Waiting for mutiple objects

    On Aug 6, 6:43*pm, David Schwartz wrote:
    > On Aug 6, 8:23*am, Sasha wrote:
    >
    > > How do I wait for multiple object, for instance, array of mutexes? I
    > > am looking for UNIX (Solaris) equivalent of WaitForMultipleObjects on
    > > Windows. I need to wait for an array of mutexes or any other sync
    > > objects and have wait function return with the index of the object
    > > that has been signaled.

    >
    > This is inappropriate. Mutexes should only be used in situations where
    > they are almost never held for any significant period of time. As
    > such, there should be no point in a 'wait for one of many mutexes'
    > function. (Just grab whichever one you want most. 99.999 times out of
    > 100 you'll just get it.)
    >
    > If you want this capability, you are doing something wrong.
    >
    > Now if you want some other kind of synchronization device that's
    > appropriate to use in a case where they are not unlocked most of the
    > time and only held briefly, you can certainly write one. The
    > pthread_cond_* functions make this easy. For that, you can add a 'wait
    > for multiple objects' function yourself.
    >
    > Perhaps the simplest way is to have each thread block on its own
    > condition variable, protected by a single mutex which also protects a
    > global linked-list of blocked threads. When you release object, you
    > traverse the linked list and mark a particular thread as to be woken
    > and then signal its condition variable. You can implement FIFO
    > semantics if you want just by adding a thread at the end of the linked
    > list and waking the first suitable thread.
    >
    > DS


    If I were designing server app on Windows I would design it this way

    1. I would create a poll of thread and two sets of arrays of events,
    each array size equal to the size of threads in the pool. One array is
    "wait" array of events that are initially not-signaled (not-available)
    and are designed to unblock a thread to process the client request.
    Another array of "process" array of events that are initially signaled
    (available) is to allow a worker thread to signal to main dispatcher
    thread that it has finished processing request and is available to
    process another request.

    2. Each thread would initially block on its own wait event of the wait
    event array.

    3. Main dispatcher thread when it needs to process request would first
    call WaitForMultipleObjects to wait on the "process" event array. If
    the call blocks it means all worker threads are busy processing
    existing requests. When any worker thread has finished processing it
    request it signals its "process" event that makes
    WaitForMultipleObjects to return with the index of the event and
    therefore index of the thread in the array that is available to
    process incoming request. Main dispatcher thread then signals
    corresponding "wait" event unblocking the worker thread.

    I can implement every aspect of this design in Solaris except
    WaitForMultipleObjects part of worker thread. It seems this function
    is not available on UNIX. I wonder how efficient multithreaded server
    design similar to what I described is implemented on UNIX platform.

  4. Re: Waiting for mutiple objects

    On Aug 7, 9:31*am, Sasha wrote:
    > On Aug 6, 6:43*pm, David Schwartz wrote:
    >
    >
    >
    >
    >
    > > On Aug 6, 8:23*am, Sasha wrote:

    >
    > > > How do I wait for multiple object, for instance, array of mutexes? I
    > > > am looking for UNIX (Solaris) equivalent of WaitForMultipleObjects on
    > > > Windows. I need to wait for an array of mutexes or any other sync
    > > > objects and have wait function return with the index of the object
    > > > that has been signaled.

    >
    > > This is inappropriate. Mutexes should only be used in situations where
    > > they are almost never held for any significant period of time. As
    > > such, there should be no point in a 'wait for one of many mutexes'
    > > function. (Just grab whichever one you want most. 99.999 times out of
    > > 100 you'll just get it.)

    >
    > > If you want this capability, you are doing something wrong.

    >
    > > Now if you want some other kind of synchronization device that's
    > > appropriate to use in a case where they are not unlocked most of the
    > > time and only held briefly, you can certainly write one. The
    > > pthread_cond_* functions make this easy. For that, you can add a 'wait
    > > for multiple objects' function yourself.

    >
    > > Perhaps the simplest way is to have each thread block on its own
    > > condition variable, protected by a single mutex which also protects a
    > > global linked-list of blocked threads. When you release object, you
    > > traverse the linked list and mark a particular thread as to be woken
    > > and then signal its condition variable. You can implement FIFO
    > > semantics if you want just by adding a thread at the end of the linked
    > > list and waking the first suitable thread.

    >
    > > DS

    >
    > If I were designing server app on Windows I would design it this way
    >
    > 1. I would create a poll of thread and two sets of arrays of events,
    > each array size equal to the size of threads in the pool. One array is
    > "wait" array of events that are initially not-signaled (not-available)
    > and are designed to unblock a thread to process the client request.
    > Another array of "process" array of events that are initially signaled
    > (available) is to allow a worker thread to signal to main dispatcher
    > thread that it has finished processing request and is available to
    > process another request.
    >
    > 2. Each thread would initially block on its own wait event of the wait
    > event array.
    >
    > 3. Main dispatcher thread when it needs to process request would first
    > call WaitForMultipleObjects to wait on the "process" event array. If
    > the call blocks it means all worker threads are busy processing
    > existing requests. When any worker thread has finished processing it
    > request it signals its "process" event that makes
    > WaitForMultipleObjects to return with the index of the event and
    > therefore index of the thread in the array that is available to
    > process incoming request. Main dispatcher thread then signals
    > corresponding "wait" event unblocking the worker thread.
    >
    > I can implement every aspect of this design in Solaris except
    > WaitForMultipleObjects part of worker thread. It seems this function
    > is not available on UNIX. I wonder how efficient multithreaded server
    > design similar to what I described is implemented on UNIX platform.- Hidequoted text -
    >
    > - Show quoted text -


    One thing I forgot to mention is that worker thread would set
    "process" event to not-signalled (not-available) immediately after it
    has been unblocked by main dispatcher thread to process request. Main
    dispatcher thread would immediately set "wait" event of the worker
    thread it has just unblocked back to not-signaled state to allow
    worker thread to block again once it has finished processing current
    request. Windows even has great API PulseEvent to immediately signal
    event unblocking the thread waiting on this event and putting it back
    to not-signaled state.

  5. Re: Waiting for mutiple objects

    On Aug 7, 6:40*am, Sasha wrote:

    > Windows even has great API PulseEvent to immediately signal
    > event unblocking the thread waiting on this event and putting it back
    > to not-signaled state.


    PulseEvent is hopelessly broken and should never be used under any
    circumstances. The problem is that PulseEvent only wakes a thread that
    is currently blocked on an event, and Windows provides you no way to
    ensure a thread is blocked on an event.

    http://blogs.msdn.com/oldnewthing/ar...05/346888.aspx

    DS


  6. Re: Waiting for mutiple objects

    On Aug 7, 6:31*am, Sasha wrote:

    > If I were designing server app on Windows I would design it this way


    > 1. I would create a poll of thread and two sets of arrays of events,
    > each array size equal to the size of threads in the pool. One array is
    > "wait" array of events that are initially not-signaled (not-available)
    > and are designed to unblock a thread to process the client request.
    > Another array of "process" array of events that are initially signaled
    > (available) is to allow a worker thread to signal to main dispatcher
    > thread that it has finished processing request and is available to
    > process another request.
    >
    > 2. Each thread would initially block on its own wait event of the wait
    > event array.


    Horrible. How can the dispatcher thread know which thread is the most
    efficient to schedule?

    > 3. Main dispatcher thread when it needs to process request would first
    > call WaitForMultipleObjects to wait on the "process" event array. If
    > the call blocks it means all worker threads are busy processing
    > existing requests. When any worker thread has finished processing it
    > request it signals its "process" event that makes
    > WaitForMultipleObjects to return with the index of the event and
    > therefore index of the thread in the array that is available to
    > process incoming request. Main dispatcher thread then signals
    > corresponding "wait" event unblocking the worker thread.


    Horrible. This means that a worker thread cannot go from doing job A
    to doing job B without a context switch through the manager thread or
    waiting for the manager thread.

    > I can implement every aspect of this design in Solaris except
    > WaitForMultipleObjects part of worker thread. It seems this function
    > is not available on UNIX. I wonder how efficient multithreaded server
    > design similar to what I described is implemented on UNIX platform.


    It's like you tried as hard as you can to make a bad design.

    How about this:

    When there's work to do, you add it to a queue. When a thread has
    nothing to do, it takes the head job off the queue and processes it.
    When there's no work to do, the first thread to notice this calls
    whatever code the manager thread would have run.

    DS

+ Reply to Thread