为什么在使用 for 和 while 循环的两个线程之间没有解决锁定条件
Why is the lock condition not resolved between two threads using for and while loop
我是线程的初学者,因此我无法自己解决这个问题。
我有两个线程应该 运行 并行。第一个线程应读取数据(模拟接收队列线程),一旦数据准备就绪,第二个线程应处理(处理线程)数据。问题是,第二个线程将无限期地等待条件变量的变化。
如果我删除第一个线程的 for 循环,条件变量将通知第二个线程,但该线程只会执行一次。为什么在for循环中使用条件变量没有通知?
我的目标是在第一个线程中读入 CSV 文件的所有数据,并根据行内容将其存储在第二个线程中的向量中。
第一个线程看起来像这样
std::mutex mtx;
std::condition_variable condVar;
bool event_angekommen{false};
void simulate_event_readin(CSVLeser leser, int sekunden, std::vector<std::string> &csv_reihe)
{
std::lock_guard<std::mutex> lck(mtx);
std::vector<std::vector<std::string>> csv_daten = leser.erhalteDatenobj();
for (size_t idx = 1; idx < csv_daten.size(); idx++)
{
std::this_thread::sleep_for(std::chrono::seconds(sekunden));
csv_reihe = csv_daten[idx];
event_angekommen = true;
condVar.notify_one();
}
}
线程二看起来像这样:
void detektiere_events(Detektion detektion, std::vector<std::string> &csv_reihe, std::vector<std::string> &pir_events)
{
while(1)
{
std::cout<<"Warte"<<std::endl;
std::unique_lock<std::mutex> lck(mtx);
condVar.wait(lck, [] {return event_angekommen; });
std::cout<<"Detektiere Events"<<std::endl;
std::string externes_event_user_id = csv_reihe[4];
std::string externes_event_data = csv_reihe[6];
detektion.neues_event(externes_event_data, externes_event_user_id);
if(detektion.pruefe_Pir_id() == true)
{
pir_events.push_back(externes_event_data);
};
}
}
我的主图是这样的:
int main(void)
{
Detektion detektion;
CSVLeser leser("../../Example Data/collectedData_Protocol1.csv", ";");
std::vector<std::string> csv_reihe;
std::vector<std::string> pir_values = {"28161","28211","28261","28461","285612"};
std::vector<std::string> pir_events;
std::thread thread[2];
thread[0] = std::thread(simulate_event_readin, leser, 4, std::ref(csv_reihe));
thread[1] = std::thread(detektiere_events,detektion, std::ref(csv_reihe), std::ref(pir_events));
thread[0].join();
thread[1].join();
}
我不是 C++ 专家,但代码似乎很容易理解,可以看出问题所在。
你的线程 1 抓住了一次锁,直到它的生命周期结束才释放它。它可能表示条件已满足,但它从未真正释放锁以允许其他线程执行操作。
要解决此问题,请在休眠后将 std::lock_guard<std::mutex> lck(mtx);
移动到 循环中。这样,线程将在每次迭代时获取和释放锁,让另一个线程有机会在休眠时采取行动。
我是线程的初学者,因此我无法自己解决这个问题。
我有两个线程应该 运行 并行。第一个线程应读取数据(模拟接收队列线程),一旦数据准备就绪,第二个线程应处理(处理线程)数据。问题是,第二个线程将无限期地等待条件变量的变化。 如果我删除第一个线程的 for 循环,条件变量将通知第二个线程,但该线程只会执行一次。为什么在for循环中使用条件变量没有通知?
我的目标是在第一个线程中读入 CSV 文件的所有数据,并根据行内容将其存储在第二个线程中的向量中。
第一个线程看起来像这样
std::mutex mtx;
std::condition_variable condVar;
bool event_angekommen{false};
void simulate_event_readin(CSVLeser leser, int sekunden, std::vector<std::string> &csv_reihe)
{
std::lock_guard<std::mutex> lck(mtx);
std::vector<std::vector<std::string>> csv_daten = leser.erhalteDatenobj();
for (size_t idx = 1; idx < csv_daten.size(); idx++)
{
std::this_thread::sleep_for(std::chrono::seconds(sekunden));
csv_reihe = csv_daten[idx];
event_angekommen = true;
condVar.notify_one();
}
}
线程二看起来像这样:
void detektiere_events(Detektion detektion, std::vector<std::string> &csv_reihe, std::vector<std::string> &pir_events)
{
while(1)
{
std::cout<<"Warte"<<std::endl;
std::unique_lock<std::mutex> lck(mtx);
condVar.wait(lck, [] {return event_angekommen; });
std::cout<<"Detektiere Events"<<std::endl;
std::string externes_event_user_id = csv_reihe[4];
std::string externes_event_data = csv_reihe[6];
detektion.neues_event(externes_event_data, externes_event_user_id);
if(detektion.pruefe_Pir_id() == true)
{
pir_events.push_back(externes_event_data);
};
}
}
我的主图是这样的:
int main(void)
{
Detektion detektion;
CSVLeser leser("../../Example Data/collectedData_Protocol1.csv", ";");
std::vector<std::string> csv_reihe;
std::vector<std::string> pir_values = {"28161","28211","28261","28461","285612"};
std::vector<std::string> pir_events;
std::thread thread[2];
thread[0] = std::thread(simulate_event_readin, leser, 4, std::ref(csv_reihe));
thread[1] = std::thread(detektiere_events,detektion, std::ref(csv_reihe), std::ref(pir_events));
thread[0].join();
thread[1].join();
}
我不是 C++ 专家,但代码似乎很容易理解,可以看出问题所在。
你的线程 1 抓住了一次锁,直到它的生命周期结束才释放它。它可能表示条件已满足,但它从未真正释放锁以允许其他线程执行操作。
要解决此问题,请在休眠后将 std::lock_guard<std::mutex> lck(mtx);
移动到 循环中。这样,线程将在每次迭代时获取和释放锁,让另一个线程有机会在休眠时采取行动。