2014-12-03 3 views
2

В настоящее время я повышающая нить как таковойзавершение бегущего импульс нить

class foo 
{ 
    private: 
    boost::shared_ptr<boost::thread> t; 
    public: 
    foo() 
    { 
    t = boost::make_shared<boost::thread>(&foo::SomeMethod,this); 
    } 
    void SomeMethod() 
    { 
    while(true) 
    { 
     .... //Does some work 
    boost::this_thread::sleep(boost::posix_time::milliseconds(5000)); //sleep for 5 seconds 
    } 
    } 

    void stopThread() 
    { 
    //Elegant and instant way of stopping thread t 
    } 
} 

Я прочитал от this поста, что вы должны определить точки прерывания, однако я не уверен, если я понимаю, как это будет вписываться в моем сценарий. Я ищу безопасный элегантный способ, гарантирующий, что нить t прекратится

ответ

3

Вы никогда не можете безопасно прекратить нить, вам просто нужно сказать ей, что она должна остановиться. Если вы прерываете поток, вы не знаете, где его прервали, и вы можете оставить систему в неизвестном состоянии.

Вместо того, чтобы зацикливать навсегда, вы можете проверить переменную (убедитесь, что она потокобезопасна, хотя!) Внутри цикла потока, чтобы увидеть, должен ли поток выйти. То, что я делаю в рабочих потоках, - это заставить меня ждать переменную условия, а затем, когда есть работа, они просыпаются и работают, но когда они проснулись, они также проверяют флаг «shutdown», чтобы проверить, должны ли они выйти.

Фрагмент моего кода:

//----------------------------------------------------------------------------- 
void Manager::ThreadMain() { 
    unique_lock<mutex> lock(m_work_mutex, std::defer_lock); 
    while(true) { 
     lock.lock(); 
     while(m_work_queue.empty() && !m_shutdown) { 
      m_work_signal.wait(lock); 
     } 

     if(!m_work_queue.empty()) { 

      // (process work...) 
      continue; 
     } 

     // quit if no work left and shutdown flag set. 
     if(m_shutdown) return; 
    } 
} 

Вы могли бы, возможно, уйти с чем-то вроде:

std::atomic<bool> stop_thread = false; 

void SomeMethod() 
{ 
    while(!stop_thread) 
    { 
    .... //Does some work 
    boost::this_thread::sleep(boost::posix_time::milliseconds(5000)); //sleep for 5 seconds 
    } 
} 

void stopThread() 
{ 
    stop_thread = true; 

    // join thread (wait for it to stop.) 
    t->join(); 
} 

И позвольте мне сказать вам, иногда это не так легко сделать что-то безопасно выйти из , Несколько недель назад у меня была большая борьба с потоковым консольным входом. В итоге мне пришлось обрабатывать непростые события консоли Windows и самостоятельно переводить их в нажатия клавиш, чтобы я мог одновременно перехватить мое пользовательское событие shutdown.

Смежные вопросы