endl osunlock int main int argc const char argv sizet remainingImages 250 mutex

Endl osunlock int main int argc const char argv sizet

This preview shows page 15 - 20 out of 22 pages.

" sees no remaining images and exits." << endl << osunlock; } int main ( int argc, const char *argv[]) { size_t remainingImages = 250; mutex counterLock; thread processors[10]; for ( size_t i = 0; i < 10; i++) agents[i] = thread(process, 101 + i, ref(remainingImages), ref(counterLock)); for (thread& agent: agents) agent.join(); cout << "Done processing images!" << endl ; return 0; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 Building a Critical Section with a Mutex 15
The way we've set it up, only one thread agent can process an image at a time! Image processing is actually serialized We can do better: serialize deciding which image to process and parallelize the actual processing Keep your critical sections as small as possible! Critical Sections Can Be a Bottleneck static void process ( size_t id, size_t & remainingImages, mutex& counterLock) { while ( true ) { size_t myImage; counterLock.lock(); // Start of critical section if (remainingImages == 0) { counterLock.unlock(); // Rather keep it here, easier to check break ; } else { myImage = remainingImages; remainingImages--; counterLock.unlock(); // end of critical section processImage(myImage); cout << oslock << "Thread#" << id << " processed an image (" << remainingImages << " remain)." << endl << osunlock; } } cout << oslock << "Thread#" << id << " sees no remaining images and exits." << endl << osunlock; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 16
What if processImage can return an error? E.g., what if we need to distinguish allocating an image and processing it A thread can grab the image by decrementing remainingImages but if it fails there's no way for another thread to retry Because these are threads, if one thread has a SEGV the whole process will fail A more complex approach might be to maintain an actual queue of images and allow threads (in a critical section) to push things back into the queue What if image processing times are *highly* variable (e.g, one image takes 100x as long as the others)? Might scan images to estimate execution time and try more intelligent scheduling What if there's a bug in your code, such that sometimes processImage randomly enters an infinite loop? Need a way to reissue an image to an idle thread An infinite loop of course shouldn't occur, but when we get to networks sometimes execution time can vary by 100x for reasons outside our control Problems That Might Arise 17
Standard mutex : what we've seen If a thread holding the lock tries to re-lock it, deadlock recursive_mutex A thread can lock the mutex multiple times, and needs to unlock it the same number of times to release it to other threads timed_mutex A thread can try_lock_for / try_lock_until : if time elapses, don't take lock Deadlocks if same thread tries to lock multiple times, like standard mutex In this class, we'll focus on just regular mutex Some Types of Mutexes 18
Something we've seen a few times is that you can't read and write a variable atomically But a mutex does so! If the lock is unlocked, lock it How does this work with caches?

  • Left Quote Icon

    Student Picture

  • Left Quote Icon

    Student Picture

  • Left Quote Icon

    Student Picture