Massive CPU-Auslastung mit std :: lock (c ++ 11)

Meine letzten Versuche, einen Thread- / Mutex-Manager zu implementieren, endeten mit einer 75% igen CPU-Auslastung (4 Kerne), während alle vier laufenden Threads entweder im Ruhezustand waren oder darauf warteten, dass ein Mutex freigeschaltet wurde.

Die spezifische Klasse ist viel zu groß, um hier vollständig veröffentlicht zu werden, aber ich könnte die Ursache auf den sicheren Erwerb zweier Mutexe eingrenzen

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

Ein anderer Teil der Klasse verwendet astd::condition_variable mitwait() undnotify_one() aufmutex1 für einige Code zur gleichen Zeit selektiv ausgeführt werden.

Der einfache Wechsel zu

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

Die CPU-Auslastung wurde auf normale 1-2% gesenkt.

Ich kann es nicht glaubenstd::lock() Funktion ist das ineffizient. Könnte dies ein Fehler in g ++ 4.6.3 sein?

edit: (Beispiel)

#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();
    }

Antworten auf die Frage(4)

Ihre Antwort auf die Frage