多线程无法正确联接
Multi-thread can't join properly
本文关键字:多线程 更新时间:2023-10-16
#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <atomic>
using namespace std;
mutex m;
condition_variable cov;
bool ready = false;
bool processed = false;
void showNum(int &f_, atomic_bool &alive_)
{
while(alive_)
{
unique_lock<mutex> lk(m);
cov.wait(lk,[]{ return ready;});
f_++;
ready = false;
processed= true;
lk.unlock();
cout<<f_<<endl;
cov.notify_one();
}
}
int main() {
vector<int> va;
for (int i = 0; i < 10; ++i) {
va.push_back(i);
}
int f = 0;
atomic_bool alive{ true };
std::thread t1(showNum,ref(f),ref(alive));
auto sizeofVector = va.size();
for (int j = 0; j < sizeofVector; ++j) {
{
lock_guard<mutex> lk0(m);
f = va.back();
cout<<f<<" ";
ready = true;
}
cov.notify_one();
va.pop_back();
{
unique_lock<mutex> lk(m);
cov.wait(lk,[]{return processed;});
processed = false;
lk.unlock();
}
}
alive = false;
t1.join();
return 0;
}
我只想在多线程中测试条件变量。上面的代码是我的测试代码。
错误是线程T1无法正确加入。我打印alive_
,这始终是正确的,在主线程中无法通过alive = false
设置为False。
我尝试使alive
成为全局变量,但仍然存在相同的错误。
你能给我一些建议吗?
可以更改
cov.wait(lk,[]{ return ready;});
to
cov.wait(lk,[&alive_]{ return ready || !alive_;});
if (!alive_)
break;
和下方 alive_=false;
添加行
cov.notify_one();
完整的代码如下
#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <atomic>
using namespace std;
mutex m;
condition_variable cov;
bool ready = false;
bool processed = false;
void showNum(int &f_, atomic_bool &alive_)
{
while(alive_)
{
unique_lock<mutex> lk(m);
cov.wait(lk,[&alive_]{return ready || !alive_;});
if (!alive_)
break;
f_++;
ready = false;
processed= true;
lk.unlock();
cout<<f_<<endl;
cov.notify_one();
}
}
int main() {
vector<int> va;
for (int i = 0; i < 10; ++i) {
va.push_back(i);
}
int f = 0;
atomic_bool alive{ true };
std::thread t1(showNum,ref(f),ref(alive));
auto sizeofVector = va.size();
for (int j = 0; j < sizeofVector; ++j) {
{
lock_guard<mutex> lk0(m);
f = va.back();
cout<<f<<" ";
ready = true;
}
cov.notify_one();
va.pop_back();
{
unique_lock<mutex> lk(m);
cov.wait(lk,[]{return processed;});
processed = false;
lk.unlock();
}
}
alive = false;
cov.notify_one();
t1.join();
return 0;
}
在t1
中,该函数不会经常测试alive
。您已经设计了它,以便每个循环都从等待条件变量开始。然后只有在通知时就开始入睡并醒来。不幸的是,当主组活着为false时,T1线程仍处于等待状态。
您可以轻松观察到:
void showNum(int &f_, atomic_bool &alive_)
{
while(alive_)
{ cout<<"waiting..."<<endl;
unique_lock<mutex> lk(m);
cout<<"waiting more..."<<endl;
cov.wait(lk,[]{ return ready;}); ///<<<<< stuck here
cout<<"go..."<<endl;
f_++;
ready = false;
processed= true;
lk.unlock();
cout<<" sn:"<<f_<<endl;
cov.notify_one();
}
}
仅当main
确保在条件变量上提供更多通知时,它才会唤醒。仅在此刻,它才能从等待状态退出,并且在处理后发现alive
是false
。
为了避免永远卡住,您可以更改代码并使用wait_for()
,以便该功能可以按时检查是否仍应保持alive
。
#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <atomic>
#include <chrono>
using namespace std;
mutex m;
condition_variable cov;
bool ready = false;
bool processed = false;
atomic_bool alive{ true };
void showNum(int &f_, atomic_bool &alive_)
{
while(alive)
{
unique_lock<mutex> lk(m);
cov.wait(lk,[]{ return ready || !alive;});
if(!alive)
break;
f_++;
ready = false;
processed= true;
lk.unlock();
cout<<f_<<endl;
cov.notify_one();
}
}
int main() {
vector<int> va;
for (int i = 0; i < 10; ++i) {
va.push_back(i);
}
int f = 0;
std::thread t1(showNum,ref(f),ref(alive));
auto sizeofVector = va.size();
for (int j = 0; j < sizeofVector; ++j) {
{
lock_guard<mutex> lk0(m);
f = va.back();
cout<<f<<" ";
ready = true;
}
cov.notify_one();
va.pop_back();
{
unique_lock<mutex> lk(m);
cov.wait(lk,[]{return processed;});
processed = false;
lk.unlock();
}
}
alive = false;
cov.notify_one();
t1.join();
return 0;
}
整合建议,我将代码修改为上面。它按照我的期望输出。感谢所有的人提供建议,最好的问候。
相关文章:
- 在C++中使用cURL和多线程
- 多线程双缓冲区
- 为什么我的多线程作业队列崩溃
- 在main()之外初始化std::vector会导致性能下降(多线程)
- 试图创建一个多线程程序来查找0-100000000之间的总素数
- 为什么一个向量上的多线程操作很慢
- 学习多线程C++:添加线程不会使执行速度更快,即使它看起来应该
- 全局变量 多读取器 一个写入器多线程安全?
- boost::文件系统::recursive_directory_iterator多线程安全
- 如何阻止TensorFlow的多线程
- 如何在多线程中正确使用unique_ptr进行多态性?
- 并发/多线程:是否可以以这种方式生成相同的输出?
- sigwait() 在多线程程序中不起作用
- 多线程程序中出现意外的内存泄漏
- 静态 constexpr 类成员变量对多线程读取是否安全?
- 多线程比没有线程C++慢
- 具有 C++11 多线程的特征库
- 通过安装信号处理程序关闭多线程应用程序
- 成员变量在多线程 C++ 时自行更改
- 尝试从头开始实现Leetcode的FizzBuzz多线程问题。收到"libc++abi.dylib: terminating"错误