2016-06-07 13 views
1

Ich bin ein Anfänger von C++ Multi Threading-Programm. Ich habe einen Dummy-Code für meine Frage erstellt. Hoge-Klasse ist Kommunikationsklasse, die Connected-Socket ist und ich nehme an, Hoge :: update() ist Datenempfangsklasse über den Socket. Und wenn bestimmte Daten angekommen sind, gibt die Hoge-Instanz die Daten zur spezifischen Verarbeitung an die Fuga-Instanz weiter.Wie vermeidet man das Blockieren von Threads während einer starken Verarbeitung in C++?

Also meine Fragen sind,

  1. Ich will nicht Hoge :: update() blockieren. Nach dem Speichern der Daten möchte ich daher th_process_data.join() nicht verwenden. Gibt es dafür eine bessere Lösung?
  2. Nach der Verarbeitung von Daten in einem anderen Thread, wie diese verarbeiteten Daten an Hoge-Instanz zurückgegeben werden. Eine Callback-Klasse ist eine Lösung?

Hoge.cc

Fuga fuga; 
Hoge::update() { 
    while(true) { 
    if(check_something()) { 
     auto data = get_data(); 
     fuga.push_data(data); 
    } 
    } 
} 

Hoge::on_received(const Data& data) { 
    std::cout << "received: " << data.id << std::endl; 
    // do something... 
} 

Fuga.cc

std::vector<Data> data_list; 
std::mutex mtx; 

Fuga::push_data(const Data& data) { 
    { 
    std::lock_guard<std::mutex> lock(mtx); 
    data_list.push_back(data); 
    } 
    std::thread th_process_data([&]{ do_processing(); }); 
    // Q1. I don't want to block this thread for Hoge::update() 
} 

Fuga::do_processing() { 
    Data data; 
    { 
    std::lock_guard<std::mutex> lock(mtx); 
    data = data_list.pop(); 
    } 

    // heavy task for data... 
    std::this_thread::sleep_for(std::chrono::seconds(3)); 

    // Q2. How to pass this processed data to Hoge::on_received(const Data& data) 
} 

Antwort

1

Ein Teil Ihrer Q ist mir nicht ganz klar, wie es scheint offen viele Möglichkeiten beendet. Ihre 2 Abfragen sind jedoch objektiv, daher versuche ich aus meinen jüngsten Erfahrungen mit Sockets zu antworten.

„1. Ich will nicht Hoge::update() blockieren. So Daten nach dem Speichern, ich nicht verwenden th_process_data.join() wollen. Gibt es eine bessere Lösung?“

In einem solchen Fall können Sie tun:

th_process_data.detach(); 

Dadurch werden Sie von Blockierung auf .join() speichern. Sie können auch std::future und std::promise Combo verwenden, wenn Ihr Design dies erlaubt. Weitere Informationen finden Sie unter this post.

„2. Nach der Verarbeitung data in einem anderen Thread, wie diese verarbeiteten Daten zurück zu Hoge Instanz. Einige Callback-Klasse Lösung?“

Ich sehe eine große Sache nicht einfach in Hoge::on_received() Methode aufrufen und die data passieren. Der Thread wird immer noch die th_process_data sein. Wenn Sie sich Sorgen darüber machen, ob Sie die Zeit dafür nutzen und die Methode sleep_for() verwenden, dann können Sie auch nach std::yield als Alternative suchen.


Nach Ihrem aktuellen Design haben Sie 2 std::mutex in 2 Methoden setzen. Ich fühle, es ist nicht erforderlich.
Denken Sie auch daran, dass Sie jedes Mal einen thread erstellen, wenn der Fuga::push_data() aufgerufen wird. Wenn diese Methode häufig aufgerufen wird und Sie die CPU nicht mit dem Aufwand der Erstellung mehrerer Threads laden möchten, sollten Sie einen einzelnen Thread einmal erstellen und darauf warten, bis die Daten empfangen werden. Aber das wird eine Änderung des Designs erfordern.