C++ 再睡一觉
我有一个对象的向量std::vector,fo对象有一个方法start(),我在这里创建特定于这个对象的线程,现在依赖于这个对象的变量,我想让它进入睡眠状态。 例如,如果我的对象是f1,变量是C++ 再睡一觉,c++,multithreading,C++,Multithreading,我有一个对象的向量std::vector,fo对象有一个方法start(),我在这里创建特定于这个对象的线程,现在依赖于这个对象的变量,我想让它进入睡眠状态。 例如,如果我的对象是f1,变量是bool sleep=false当sleep变量为true时,我希望它进入睡眠状态 我试过这种方法,但似乎不起作用。我认为如果 class fo { public : thread* t ; bool bedient = false , spazieren = false; voi
bool sleep=false代码>当sleep变量为true时,我希望它进入睡眠状态
我试过这种方法,但似乎不起作用。我认为如果
class fo {
public :
thread* t ;
bool bedient = false , spazieren = false;
void start(){
t = new thread([this]() {
while (!this->bedient){
if (this->spazieren == true){
std::this_thread::sleep_for(std::chrono::seconds(10));
this->spazieren = false ;
}
}
this->join();
});
}
void join(){
t->join(); delete t;
}
};
您的代码“产生”了很多问题:
(一)
在一个线程中设置任何类型的变量在任何其他线程中都可能不可见。如果你想让其他线程在第一个线程中看到你的更改,你必须同步你的内存。这可以通过使用std::mutex
来实现,在每次数据更改时使用锁定和解锁,或者使用std::atomic
变量来实现,这些变量本身或许多其他方法都可以实现同步。请阅读一本关于多线程编程的书
(二)
您尝试加入自己的线程。那根本不是正确的用法。任何线程都可以在其他执行端连接,但不能在自身上连接。那没有道理
(三)
如果您没有手动设置“sleep”变量,那么您的线程正在运行一个循环,只是什么也不做。一个加热你的核心和地球的好方法;)
fo类{
公众:
std::thread*t=nullptr;//如果没有调用start(),则防止损坏的删除!
std::原子bedient=false;
std::原子spazieren=false;
void start()
{
t=新的标准::线程([此]()
{
而(!this->bedient)
{
如果(此->spazieren==true)
{
std::cout我会尝试重构您的代码,以使用std::future而不是std::thread,此外,我相信短期内您会遇到一些问题
您不应该在加入线程时尝试加入。也就是说,您拥有的代码永远不会终止。您定义的lambda将尝试调用join,但是,lambda将永远不会返回,因为它正在等待加入,而当lambda这样做时,它只会自己返回。换句话说,您告诉它等待自己。
您向外界透露了太多关于类功能的信息。我建议将实现细节移到.cc中,而不是放在类声明中。但是,除此之外,您还提供了对控制变量spazieren和bedient的即时访问。这是一个问题,因为它使控制流无效,使抽象性变弱
你的bool不是原子的。如果你试图从线程外修改它们,你会遇到崩溃。在某些环境中,这些崩溃可能是零星的,并且很难调试
如果你绝对需要尽快完成一项任务,那么只有在被问到的时候睡觉才有用,但是要注意,这会使内核达到最大值,如果部署到错误的环境中,可能会导致重大问题和速度减慢。我不知道这个计划的最终目标是什么,但我建议考虑在下面更改产量例如,从ng代码到一段睡眠时间,10毫秒应该足以防止给cpu带来太多压力
对于您的实现,您的线程是否处于活动运行状态尚不清楚。我建议您考虑使用一个额外的bool来指示它是否正在运行,这样您就可以更正确地决定在多次调用start()时该怎么做
当这个对象解构时,如果线程仍在运行,它将崩溃。你需要确保在解构程序完成运行之前加入
我会考虑以下重构:
#include <memory>
#include <future>
#include <atomic>
class fo
{
public:
~fo()
{
this->_bedient = true;
_workThread.wait();
}
void start()
{
_workThread = std::async(std::launch::async, [this]() -> bool
{
while(!this->_bedient)
{
if(true == this->_spazieren)
{
std::this_thread::sleep_for(std::chrono::seconds(10));
this->_spazieren = false;
}
else
{
std::this_thread::yield();
}
}
return true;
});
}
void ShouldSleep(bool shouldSleep)
{
this->_spazieren = shouldSleep;
}
void ShouldStop(bool shouldStop)
{
this->_bedient = !shouldStop;
}
private:
std::future<bool> _workThread = {};
std::atomic<bool> _bedient{ false };
std::atomic<bool> _spazieren{ false };
};
#包括
#包括
#包括
fo类
{
公众:
~fo()
{
此->\u bedient=true;
_workThread.wait();
}
void start()
{
_workThread=std::async(std::launch::async,[this]()->bool
{
而(!this->\u bedient)
{
如果(true==此->\u spazieren)
{
std::this_thread::sleep_for(std::chrono::seconds(10));
这个->\u spazieren=false;
}
其他的
{
std::this_thread::yield();
}
}
返回true;
});
}
虚空应睡(布尔应睡)
{
这个->\u spazieren=应该睡觉;
}
无效应停止(布尔应停止)
{
这个->\u bedient=!应该停止;
}
私人:
std::future_workThread={};
std::原子_bedient{false};
std::原子_spazieren{false};
};
不清楚你在问什么,但如果你问标题上写了什么,你就不能按照标准来做。如果你需要“睡觉”,你可能做错了。你可能想重新访问你的代码设计。你可能想要一个条件变量,而不是一个sleep bool hack的东西。在我写答案之前…我通常的问题是:你到底想做什么?正如其他人所建议的,问另一个线程“睡眠”是一个不正确设计的指示器。但也许你真正的意思是你希望线程在继续之前等待一些东西。有各种各样的好模式。精心设计,你会得到更好的建议。@MichaelChourdakis我有一个服务器线程和cafe客户端线程,我希望能够将如果队列长度超过特定的大小(我知道这是一种繁忙的等待),客户端将使用状态变量休眠。我可以想象start()
#include <memory>
#include <future>
#include <atomic>
class fo
{
public:
~fo()
{
this->_bedient = true;
_workThread.wait();
}
void start()
{
_workThread = std::async(std::launch::async, [this]() -> bool
{
while(!this->_bedient)
{
if(true == this->_spazieren)
{
std::this_thread::sleep_for(std::chrono::seconds(10));
this->_spazieren = false;
}
else
{
std::this_thread::yield();
}
}
return true;
});
}
void ShouldSleep(bool shouldSleep)
{
this->_spazieren = shouldSleep;
}
void ShouldStop(bool shouldStop)
{
this->_bedient = !shouldStop;
}
private:
std::future<bool> _workThread = {};
std::atomic<bool> _bedient{ false };
std::atomic<bool> _spazieren{ false };
};