Question

I have the following scenario:

I have multiple worker threads running that all go through a certain section of code, and they're allowed to do so simultaneously. No critical section surrounds this piece of code right now as it's not required for these threads.

I have a main thread that also -occassionally- wants to enter that section of code, but when it does, none of the other worker threads should use that section of code.

Naive solution: surround the section of code with a critical section. But that would kill a lot of parallelism between the worker threads, which is important in my case.

Is there a better solution?

Was it helpful?

Solution

Use RW locks. RW locks allow multiple readers and only a single writer. Your workers would call read-lock at the start of the critical section and the main thread would write-lock.

By definition, when calling read-lock, the calling process will wait for any writing threads to finish. When calling write-lock, the calling process will wait for any reading or writing threads to finish.

Example using POSIX threads:

pthread_rwlock_t lock;
/* worker threads */
void *do_work(void *args) {
    for (int i = 0; i < 100; ++i) {
        pthread_rwlock_rdlock(&lock);
        // do some work...
        pthread_rwlock_unlock(&lock);
        sleep(1);
    }
    pthread_exit(0);
}

/* main thread */
int main(void) {
    pthread_t workers[4];
    pthread_rwlock_init(&lock);
    int i;

    // spawn workers...
    for (i = 0; i < 4; ++i) {
        pthread_create(workers[i]; NULL, do_worker, NULL);
    }
    for (i = 0; i < 100, ++i) {
        pthread_rwlock_wrlock(&lock);
        // do some work...
        pthread_rwlock_unlock(&lock);
        sleep(1);
    }

    return 0;
}

OTHER TIPS

As far as I understand it, your worker threads are started asynchronously. So when the main thread wants to run this code section, you have to ensure that no worker thread is executing it. Therefore you have to stop all worker threads before the main thread can enter that code section, and allow them to enter it again afterwards.
This could be done - using Grand Central Dispatch - if your worker threads would be assigned to a dispatch group, see https://developer.apple.com/library/mac/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html.
The main thread could then send the message dispatch_group_wait to this dispatch group, wait for all worker thread to leave this code section, execute it, and then requeue the worker threads.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top