【问题标题】:C++ Threads Deadlock Mutex Lock AbortedC++ 线程死锁互斥锁中止
【发布时间】:2017-09-16 10:12:32
【问题描述】:

我正在尝试从程序中消除死锁。问题是程序一直让我中止。重点是将数据写入文件。但是当发生死锁时,线程应该等待并稍后继续,而不是中止。

#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

如何避免中止,让线程等待。

更新:包含所有相关代码...

【问题讨论】:

  • 发生死锁时,所有个相关线程都被阻塞等待,没有一个可以继续,定义。你的问题没有意义。任何死锁情况的解决方案是始终以相同的顺序获取锁。
  • mtx.unlock() 告诉您“代码将永远不会被执行”,您不会收到一个很大的警告。 ?如果没有,请打开编译器警告。
  • 不,我没有收到警告
  • @johnS 编译时打开-Wall标志。
  • 我做了,但没有警告

标签: c++ multithreading locking mutex deadlock


【解决方案1】:

不要手动 lock() / unlock() 互斥锁。这很容易出错。请改用guardsmtx.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::mutex> lock1(mtx1);
    std::lock_guard<std::mutex> lock2(mtx2);
    // ... exception thrown somewhere
}

这是有保证的,因为std::lock_guard 的析构函数保证会以与构造相反的顺序被调用。

【讨论】:

  • 你是说我不能通过使用锁定/解锁手动修复它
  • @johnS 这不是我要说的。您可以在catch 正文中调用解锁。不过这很容易出错。
  • 我想了解它是如何工作的,因此采用了这种方法
  • @johnS 另请注意throw new exception(); 是错误的。我已经在我的示例中纠正了这一点。
  • 即使我使用 std::lock_guard<:mutex> lock(mtx);,我仍然得到相同的输出
猜你喜欢
  • 2023-03-09
  • 1970-01-01
  • 2015-10-26
  • 1970-01-01
  • 1970-01-01
  • 2013-01-31
  • 1970-01-01
  • 1970-01-01
  • 2012-03-01
相关资源
最近更新 更多