简体   繁体   中英

How do I wait for multiple semaphores using dispatch on Mac?

On Windows, I am using WaitForMultipleObjects() to wait for multiple semaphores using the following code.

DWORD waitobject = WaitForMultipleObjects( cnt, semaphores, false, INFINITE );

return waitobject - WAIT_OBJECT_0;

I tried using dispatch_semaphore_wait() on Mac without success using the following code.

while( true )
    for( int = 0;  i < semaphoreCnt;  ++i )
        if( dispatch_semaphore_wait( semaphores[ i ], DISPATCH_TIME_NOW ) == 0 )
            return i;

It keeps waiting and never finishes. Any ideas why?

What I am trying to achieve is that the code wait for one of the given semaphores is signalled and give back which one.

I mean the code, as written should work - if I plug it into a very simple objective-c program it behaves as expected:

#import <Foundation/Foundation.h>
#import <pthread.h>

int wait_on_a_sema(int sema_count, dispatch_semaphore_t __strong *sema)
{
    while (true) {
        for (int i = 0; i < sema_count; i++) {
            if (dispatch_semaphore_wait(sema[i], DISPATCH_TIME_NOW) == 0) {
                return i;
            }
        }
    }
}

void* PosixThreadMainRoutine(void* data)
{
    // Do some work here.
    sleep(5);
    dispatch_semaphore_signal((__bridge dispatch_semaphore_t)data);
    return NULL;
}
 
void LaunchThread(dispatch_semaphore_t __strong sema)
{
    // Create the thread using POSIX routines.
    pthread_attr_t  attr;
    pthread_t       posixThreadID;
    int             returnVal;
 
    returnVal = pthread_attr_init(&attr);
    assert(!returnVal);
    returnVal = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    assert(!returnVal);
 
    int     threadError = pthread_create(&posixThreadID, &attr, &PosixThreadMainRoutine, (__bridge void *)sema);
 
    returnVal = pthread_attr_destroy(&attr);
    assert(!returnVal);
    if (threadError != 0)
    {
         // Report an error.
    }
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        dispatch_semaphore_t sems[10];
        for (int i = 0; i < 10; i++) {
            sems[i] = dispatch_semaphore_create(0);
        }
        NSLog(@"Hello, World!");
        int item = arc4random_uniform(10);
        LaunchThread(sems[item]);
        int ret = wait_on_a_sema(10, sems);
        NSLog(@"%d - %d", ret, item);
    }
    return 0;
}

I can even alter the wait function to display a form of progress -

time_t start_time = time(0);
uint64_t loopcount = 0;
while (true) {
    loopcount++;
    time_t curr_time = time(0);
    if (curr_time > start_time) {
        NSLog(@"LoopCount: %llu", loopcount);
        start_time = curr_time;
    }

And you can see it display the significant number of times the loop is gone through in the 5 seconds.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM