How to fix C ++ thread lock example

I have a far-fetched dead end in C ++ 11. This is achieved using two separate functions with a pool of several threads. How can this example be removed to avoid a dead end? I think the solution has something to do with sequentially streamlining lock procedures.

#include <thread>
#include <mutex>
#include <iostream>

std::mutex kettle;
std::mutex tap;

#define THREAD_POOL 8

void kettle_tap(){

    std::cout << "Locking kettle in " << std::this_thread::get_id() << std::endl;
    // Lock the mutex kettle by creating and using lock_guard kettle_lock.
    std::lock_guard<std::mutex> kettle_lock(kettle);
    std::cout << "Locked kettle in " << std::this_thread::get_id() << std::endl;

    std::cout << "Locking tap in " << std::this_thread::get_id() << std::endl;
    // Lock the mutex tap by creating and using lock_guard tap_lock.
    std::lock_guard<std::mutex> tap_lock(tap);
    std::cout << "Locked tap in " << std::this_thread::get_id() << std::endl;

    std::cout << "Filling kettle in " << std::this_thread::get_id() << std::endl;
}

void tap_kettle(){

    std::cout << "Locking tap in " << std::this_thread::get_id() << std::endl;
    // Lock the mutex tap by creating and using lock_guard tap_lock.
    std::lock_guard<std::mutex> tap_lock(tap);
    std::cout << "Locked tap in " << std::this_thread::get_id() << std::endl;

    std::cout << "Locking kettle in " << std::this_thread::get_id() << std::endl;
    // Lock the mutex kettle by creating and using lock_guard kettle_lock.
    std::lock_guard<std::mutex> kettle_lock(kettle);
    std::cout << "Locked kettle in " << std::this_thread::get_id() << std::endl;

    std::cout << "Filling kettle in " << std::this_thread::get_id() << std::endl;

}

int main(){

    std::thread pool[THREAD_POOL];

    for (int t = 0; t < THREAD_POOL; t += 2){
        pool[t]   = std::thread(kettle_tap);
        pool[t+1] = std::thread(tap_kettle);
    }

    for (int t = 0; t < THREAD_POOL; ++t){
        pool[t].join();
    }

    std::cout << "Threads are all joined" << std::endl;

    return 0;

}
+4
source share
2 answers

std::lock(Mutexes...)

In your case, both kettle_tap()and tap_kettle()have to start with:

std::lock(tap, kettle);

but the order of the mutex arguments does not matter, so it may be different for both functions.

Lock multiple mutexes

, , .

, , try_lock unlock, , ( - ).

(, - , ), , ( ), .

, std::lock_guard:

std::lock(tap, kettle);
std::lock_guard<std::mutex> kettle_lock(kettle, std::adopt_lock);
std::lock_guard<std::mutex> tap_lock(tap, std::adopt_lock);
+6

. , . , , kettle_lock tap_lock tap_kettle. , .

+2

All Articles