// std::lock example
#include <iostream>       // std::cout
#include <thread>         // std::thread
#include <mutex>          // std::mutex, std::lock

// clang's thread sanitizer
// clang++-5.0 -std=c++11 6.cpp -fsanitize=thread -fPIE -pie -g
//                              =================
// then run
std::mutex m1,m2; // standard mutex, requires lock and unlock

#define xDEADLOCK_POSSIBLE
// WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock) (pid=21772)


void task_a()
{
    for( int i=0; i<1000; ++i ) {
#ifdef DEADLOCK_POSSIBLE
        m1.lock();
        m2.lock();
#else
        std::lock( m1,m2 ); // any number of mutexes
        // https://stackoverflow.com/questions/13667810/massive-cpu-load-using-stdlock-c11
#endif
        std::cout << "task a" << i << "\n";
        m1.unlock();
        m2.unlock();
    }
}

void task_b()
{
    for( int i=0; i<1000; ++i ) {
#ifdef DEADLOCK_POSSIBLE
        m2.lock();
        m1.lock();
#else
        std::lock( m1,m2 );
#endif
        std::cout << "task b" << i << "\n";
        m2.unlock();
        m1.unlock();
    }
}

int main()
{
    std::thread th1( task_a );
    std::thread th2( task_b );
    th1.join();
    th2.join();
    return 0;
}