C++ 再睡一觉

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

我有一个对象的向量std::vector,fo对象有一个方法start(),我在这里创建特定于这个对象的线程,现在依赖于这个对象的变量,我想让它进入睡眠状态。 例如,如果我的对象是f1,变量是
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 };
    };