'std :: system_error',生产者使用者C ++并发[关闭]

问题描述 投票:-1回答:1

下面的生产者/消费者程序应该一次将一个字符传送到缓冲区,然后打印它。该程序最初运行,但随后总是在使用者循环的第三次迭代中失败。 -pthread包含在编译时。

程序应该能够遍历'poem'变量,最终导致逐个字符地打印出整首诗。

#include <iostream>
#include <cmath>
#include <cstdlib>
#include <thread>
#include <fstream>
#include <chrono>
#include <mutex>
#include <condition_variable>
#include <vector>
#include <queue>

using namespace std;

mutex mtx;
condition_variable cond_var;
int thread_ID = 1;

vector<char> txtImport(vector<char> output){
  ifstream file("poem.txt");
  char character;
  while (file.get(character)){
    output.push_back(character);
  }
  return output;
}

void producer(vector<char> poem, char* buffer, int poem_size) {
  cout << "\n\nPROD-  \n";
  int poem_position = 68;
  const int producer_ID = 1;
  unique_lock<mutex> lock(mtx);
  while(true){
    cout << "\n1";
    if(poem_position == poem_size) {exit(1);}
    if(thread_ID!=producer_ID) {cond_var.wait(lock);}
    else{
      cout << "\nlock\n";

      *buffer = poem[poem_position];
      poem_position += 1;
      thread_ID = 2;

      cout << poem_position << " 2 \n";
      cout << poem[poem_position] << " 4 \n";
      cout << "CHAR: " << *buffer << " \n------\n\n";

      lock.unlock();
      cond_var.notify_all();
      std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }
  }
}

void consumer(char* buffer){
  cout << "\n\n       -CONS\n";
  const int consumer_ID = 2;
  unique_lock<mutex> lock(mtx);
  while(true){
    cout << "\n       one ";
    if(thread_ID!=consumer_ID) {cond_var.wait(lock);}
    else{
      cout << "\n       lock\n";
      cout << "       ->" << *buffer << " <-\n\n";
      thread_ID = 1;
      lock.unlock();
      cond_var.notify_all();
      std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }
  }
}

int main(void) {

    vector<char> poem;
    poem = txtImport(poem);
    char buffer = 'z';
    int poem_size = poem.size();

    cout << "\n--MAIN--\n";

    thread thread_two(consumer, &buffer);
    thread thread_one(producer, poem, &buffer, poem_size);


    thread_one.join();
    thread_two.join();

    return 0;

}

程序输出为:

--MAIN--


       -CONS

       one 

PROD-  

1
lock
69 2 
b 4 
CHAR: m 
------


       one 
       lock
       ->m <-


1
lock
70 2 
e 4 
CHAR: b 
------


       one 
       lock
       ->b <-

terminate called after throwing an instance of 'std::system_error'
terminate called recursively
  what():  Aborted (core dumped)
c++ concurrency condition-variable
1个回答
2
投票

您有不确定的行为。

cond_var.wait被调用时,传递的互斥锁必须被当前线程锁定。它不会在您的代码中发生(第一次迭代除外)。

您的情况:

unique_lock<mutex> lock(mtx);
while (true)
   cond_var.wait(lock);
   lock.unlock();

所以在while循环的第二次迭代中,当wait被调用时,lock被解锁。错误。

要修复,将unique_lock构造移到both]中(消费者/生产者函数中的相同问题)while循环。


lock-类型为std :: unique_lock的对象,必须为被当前线程锁定

来自condition_variable::wait reference

© www.soinside.com 2019 - 2024. All rights reserved.