Carga masiva de la CPU usando std :: lock (c ++ 11)

Mis esfuerzos recientes para implementar un administrador de subprocesos / mutex terminaron en una carga de CPU del 75% (4 núcleos), mientras que los cuatro subprocesos en ejecución estaban en suspensión o esperando un desbloqueo mutex.

La clase específica es demasiado grande para publicarla aquí por completo, pero podría reducir la causa a la adquisición de dos mutexes a salvo de un punto muerto.

std::unique_lock<std::mutex> lock1( mutex1, std::defer_lock );
std::unique_lock<std::mutex> lock2( mutex2, std::defer_lock );
std::lock( lock1, lock2 );

Otra parte de la clase usa unstd::condition_variable conwait() ynotify_one() enmutex1 para que algún código sea ejecutado selectivamente al mismo tiempo.

El simple cambio a

std::unique_lock<std::mutex> lock1( mutex1 );
std::unique_lock<std::mutex> lock2( mutex2 );

redujo el uso de la CPU al 1-2% normal.

No puedo creer, elstd::lock() La función es esa ineficiente. ¿Podría ser esto un error en g ++ 4.6.3?

editar: (ejemplo)

#include <atomic>
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>

std::mutex mutex1, mutex2;
std::condition_variable cond_var;

bool cond = false;
std::atomic<bool>done{false};

using namespace std::chrono_literals;

void Take_Locks()
    {
    while( !done )
        {
        std::this_thread::sleep_for( 1s );

        std::unique_lock<std::mutex> lock1( mutex1, std::defer_lock );
        std::unique_lock<std::mutex> lock2( mutex2, std::defer_lock );
        std::lock( lock1, lock2 );

        std::this_thread::sleep_for( 1s );
        lock1.unlock();
        lock2.unlock();
        }
    }

void Conditional_Code()
    {
    std::unique_lock<std::mutex> lock1( mutex1, std::defer_lock );
    std::unique_lock<std::mutex> lock2( mutex2, std::defer_lock );

    std::lock( lock1, lock2 );
    std::cout << "t4: waiting \n";

    while( !cond )
        cond_var.wait( lock1 );

    std::cout << "t4: condition met \n";
    }

int main()
    {
    std::thread t1( Take_Locks ), t2( Take_Locks ), t3( Take_Locks );
    std::thread t4( Conditional_Code );

    std::cout << "threads started \n";
    std::this_thread::sleep_for( 10s );

    std::unique_lock<std::mutex> lock1( mutex1 );
    std::cout << "mutex1 locked \n" ;
    std::this_thread::sleep_for( 5s );

    std::cout << "setting condition/notify \n";
    cond = true;
    cond_var.notify_one();
    std::this_thread::sleep_for( 5s );

    lock1.unlock();
    std::cout << "mutex1 unlocked \n";
    std::this_thread::sleep_for( 6s );

    done = true;
    t4.join(); t3.join(); t2.join(); t1.join();
    }

Respuestas a la pregunta(4)

Su respuesta a la pregunta