2017-09-16 6 views
-3

Ich versuche, einen Deadlock aus einem Programm zu entfernen. Das Problem ist, dass das Programm mich immer wieder abbricht. Der Punkt ist, Daten in eine Datei zu schreiben. Wenn jedoch ein Deadlock auftritt, sollte der Thread warten und später fortfahren anstatt abzubrechen.C++ Threads Deadlock Mutex Sperre abgebrochen

#include <iostream> 
#include <unistd.h> 
#include <fstream> 
#include <vector> 
#include <thread> 
#include <mutex> 
#include <exception> 
#include <condition_variable> 

using namespace std; 

std::mutex mtx; 
ofstream myfile; 
condition_variable cv; 

void lock() 
{ 
    mtx.lock(); 
} 

void unlock() 
{ 
    mtx.unlock(); 
} 

void writeToFile(int threadNumber){ 
myfile << "["; 
    for(int j =1; j <= 10; j++){ 
     int num = j * threadNumber; 
     string line = std::to_string(num) + " "; 
     myfile << line; 
    } 
    myfile << "]"; 
//mtx.unlock(); 
} 

void threadFunction(int threadNumber) 
{ 
// int x = 0; 
// int y = 0; 

    try{ 
    lock(); 
    if (threadNumber % 2 == 0) 
     sleep(rand() % 4 + 1); 
    writeToFile(threadNumber); 
    throw exception(); 
    unlock(); 
    } 
    catch(...){ 
    cout << "Something went wrong!" << endl; 
    throw exception(); 
    } 
} 


int main (int argc, char const *argv[]) { 
myfile.open ("mutex.txt"); 
    std::set_terminate([](){ 
    std::cout << "Unhandled exception\n"; 
    // Here I want to fix the deadlock if something goes wrong. But I keep getting Abroted 

    }); 
     int len; 
     cout << "Enter Number of threads : "; 
     cin >> len; 
     std::thread t[len + 1]; 
     for(int i =1; i <= len;i++){ 
      t[i] = std::thread(threadFunction, i); 
      cout << "Created Thread : " <<t[i].get_id()<<endl; 
      } 

      for(int i =1; i <= len;i++){ 
      t[i].join(); 
      } 
     myfile.close(); 
     return 0; 
} 

Ausgabe

Enter Number of threads : 5 
Created Thread : 1992414288 
Created Thread : 1982854224 
Created Thread : 1974465616 
Created Thread : 1966077008 
Created Thread : 1957688400 
Something went wrong! 
Unhandled exception 
Aborted 

Wie kann ich die abgebrochenen vermeiden und den Faden warten lassen.

Update: Enthalten alle relevanten Code ...

+0

Wenn ein Deadlock auftritt, werden * alle * betroffenen Threads blockiert, die auf einander warten, und * keine * von ihnen können * per Definition * weitermachen. Deine Frage ergibt keinen Sinn. Die Lösung für eine Deadlock-Situation besteht darin, die Sperren immer in der gleichen Reihenfolge zu erfassen. – EJP

+0

Erhalten Sie keine große phat Warnung auf diesem 'mtx.unlock()' sagt Ihnen, "Code wird nie ausgeführt werden." ? Wenn nicht, zeigen Sie Ihre Compiler-Warnungen an. – WhozCraig

+0

Nein, ich bekomme keine Warnung –

Antwort

2

Sie manuell nicht lock()/unlock() mutexes. Das ist fehleranfällig. Verwenden Sie stattdessen guards. mtx.unlock(); nach dem Auslösen der Ausnahme wird nicht aufgerufen.

Hier ist, wie Ihr Code aussehen soll:

try{ 
    std::lock_guard<std::mutex> lock(mtx); 
    if (threadNumber % 2 == 0) 
     sleep(rand() % 4 + 1); 
    writeToFile(threadNumber); 
    throw exception(); 
    } 
    catch(...){ 
    cout << "Something went wrong!" << endl; 
    throw exception(); 
    } 

Um Deadlocks im Allgemeinen zu vermeiden, dass das Verriegeln und Entriegeln mehrerer mutexes in umgekehrter Reihenfolge getan werden muss. Also, wenn ein Thread nutzt so etwas wie

{ 
    std::lock_guard<std::mutex> lock1(mtx1); 
    std::lock_guard<std::mutex> lock2(mtx2); 
    // ... exception thrown somewhere 
} 

dies, da die Destruktoren von std::lock_guard garantiert sind garantiert in umgekehrter Reihenfolge aufgerufen werden diese gebaut wurden.

+0

Also sagst du, dass ich es nicht manuell reparieren kann, indem ich lock/unlock benutze –

+0

@johnS Das ist nicht genau was ich sage. Sie können die Sperre im "catch" -Körper aufrufen. Das ist jedoch fehleranfällig. – user0042

+0

Ich versuche zu verstehen, wie alles funktioniert, daher der Ansatz –