Search code examples
c++boostasynchronousboost-mutex

Process while waiting for mutex lock


Is there some way to execute a code section while waiting for a mutex to lock?

The only true internal hit to my application's performance is database interaction, and there are times where I need strict synchronization which because of the database interaction may cause contention, so I'd like to use the time waiting for a lock to get data from the database.

For example, I'd like the code to look something like, in pseudo:

boost::unique_lock<boost::mutex> process_lock(process_mutex, work_while_contending);
//code to execute while lock contending
process_lock.proceed_after_lock();

I've examined boost's synchronization section, and while futures and recursive sound like my intent could be achieved, but I can't figure out how to implement my intent.

How can my intent be implemented?


Solution

  • You don't really want to do this in most cases. If you do want to do it, you probably want to use futures, like this:

    auto f = std::async(std::launch::async, [&]() {
       // do work in another thread here.
    });
    
    boost::unique_lock<boost::mutex> process_lock(process_mutex);
    auto result = f.get();
    
    // proceed here the work is done and you have the lock
    

    ... This lets you do work in another thread while the original thread is waiting for the mutex. Once both the work is complete and the mutex is acquired the thread continues. If the work finishes before the mutex is acquired then the work thread will go away and the original thread will just be idle waiting for the mutex.

    Here's why you don't want to do this: If you acquire the mutex before the work completes then no other thread will be able to acquire the mutex, the program will stall while it waits for the "background" work to complete.

    A possible solution is to use a busy wait loop with a non-blocking try_lock. The potential problem here is that the thread is not waiting for the mutex, so there is no guarantee that the thread will ever get ahold of it. If there is a lot of contention for it, and others are actively waiting, then you'll never get it. If you wait for it, then typically the OS will guarantee some sort of order such that you will eventually get it. If you're not waiting, that guarantee cannot be made.