2017-09-16 4 views
-3

プログラムからデッドロックを削除しようとしています。問題は、プログラムが私に中止を与え続けていることです。ポイントは、ファイルにデータを書き込むことです。しかし、デッドロックが発生すると、スレッドは中断するのではなく、後で続行して待機する必要があります。C++スレッドデッドロックミューテックスロック中止

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

出力

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 

どのように私は中止されたを回避し、スレッドを待機させることができます。

更新:含まれ、関連するすべてのコード...

+0

デッドロックが発生すると、関係する* all *スレッドはお互いを待ってブロックされ、* none *は定義*によって継続できます。あなたの質問は理にかなっていません。デッドロックの状況を解決するには、常に同じ順序でロックを取得する必要があります。 – EJP

+0

''コードは決して実行されません "と言っている' 'mtx.unlock()'に大きなphat警告はありませんか? ?そうでなければ、コンパイラの警告を出してください。 – WhozCraig

+0

いいえ私は警告を受け取りません –

答えて

2

はないlock()/unlock()ミューテックス手動で行います。それはエラーが起こりやすい。代わりにguardsを使用してください。例外をスローした後のmtx.unlock();は呼び出されません。

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

を複数のミューテックスのロックとロック解除は逆の順序で行われる必要があることを、一般的にデッドロックを回避するには:ここで

は、あなたのコードがどのように見えるべきかです。だから、あるスレッドがstd::lock_guardのデストラクタは、これらが構築された逆の順序で呼び出されることが保証されているので、これは保証され

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

のようなものを使用している場合。

+0

ロック/アンロックを使って手動で修正することはできないと言っています –

+0

@johnSそれは私が言っていることではありません。あなたは 'catch'ボディでunlockを呼び出すことができるかもしれません。それは間違いやすいです。 – user0042

+0

私はそれがどのように動作しているのか理解しようとしています。したがって、 –

関連する問題