【问题标题】:Exceptions while using mutex and condition_variable使用互斥锁和条件变量时的异常
【发布时间】:2018-01-24 20:45:08
【问题描述】:

我正在编写一个程序来从 .txt 文件中读取数据并在输出 .txt 文件中使用它。我正在使用两个线程;第一个线程用于从 .txt 文件中读取数据,第二个线程用于将其写入输出文件。我是互斥锁和条件变量编程的初学者,我的程序以某种方式处理异常......异常是

abort() has been called.

这是两个线程方法:

void MessagesSender::readsData()
{
    ifstream data;
    data.open("data.txt");
    string buffer;
    bool toEmpty = false;
    std::unique_lock<mutex> locker(mtx, std::defer_lock);
    if (data.is_open())
    {
        while (std::getline(data, buffer)) //reads line to the buffer.
        {
            locker.lock();
            this->messages.push(buffer); //push the message to the queue.
            locker.unlock();
            cond.notify_one();
        }
        data.close();
        toEmpty = true;
    }
    else
    {
        cout << "Error opening file... " << endl;
    }
    if (toEmpty) //empty the data file.
    {
        ofstream emptyFile; 
        emptyFile.open("data.txt", ofstream::out | ofstream::trunc);
        emptyFile.close();
    }
}

void MessagesSender::sendsData()
{
    ofstream output;
    output.open("output.txt");
    string tempString;
    string tempMessage;

    if (output.is_open())
    {
        std::unique_lock<mutex> locker(mtx, std::defer_lock);
        locker.lock();
        cond.wait(locker);
        while (!(this->messages.empty()))
        {
            tempMessage = this->messages.front();
            this->messages.pop();
            locker.unlock();
            for (std::vector<string>::iterator it = this->userNames.begin(); it != this->userNames.end(); ++it)
            {
                tempString = *it;
                tempString += ": ";
                tempString += tempMessage;
                tempString += "\n";
                output << tempString;
            }
        }
        output.close();
    }
    else
    {
        cout << "Error opening file... " << endl;
    }
}

为什么程序处理异常?

【问题讨论】:

  • 您是否使用调试器确定了违规行?
  • “abort() 已被调用”也不例外。如果抛出异常但未被捕获,您会收到包含异常类型的更详细消息。
  • @FrançoisAndrieux 我不能,因为线程的工作非常不稳定......
  • @I.Klein “因为线程的工作很不稳定” 嗯??
  • @I.Klein 我不明白你的意思。大多数调试器将能够在abort 上中断,为您提供一个很好的调用堆栈。

标签: c++ multithreading mutex condition-variable


【解决方案1】:

一个可能的错误是您在while 循环中反复解锁mutex,即使互斥锁未锁定:

if (output.is_open())
    {
        std::unique_lock<mutex> locker(mtx, std::defer_lock);
        locker.lock();
        cond.wait(locker);
        while (!(this->messages.empty()))
        {
            tempMessage = this->messages.front();
            this->messages.pop();
            // if multiple messages are in the queue, you unlock multiple times 
            // even though the mutex is not locked
            locker.unlock();   
            for (std::vector<string>::iterator it = this->userNames.begin(); it != this->userNames.end(); ++it)
            {
                tempString = *it;
                tempString += ": ";
                tempString += tempMessage;
                tempString += "\n";
                output << tempString;
            }
        }
        output.close();
    }

根据unique_lock::unlock,这会引发std::system_error

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-06
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-19
    • 1970-01-01
    相关资源
    最近更新 更多