c++ - boost::this_thread::sleep_用于使整个程序休眠

标签 c++ multithreading boost pthreads c++98

C++ 98和Boost 1.54

我在弄清楚为什么使用boost::this_thread::sleep_for会使我的整个程序处于休眠状态时遇到了麻烦。调用Wait()函数的唯一时间和地点是在此线程内,并且该线程的唯一目的是读取目录中的文件名并触发上载。

但是由于某种原因,当它到达boost::this_thread::sleep_for函数中的Wait()行时,它卡在那里并且还休眠所有其他线程。我不确定自己缺少什么,因此我们将不胜感激。

代码:

void Upload::ReadFileNames()
{
    cout << "[DEBUG] ReadFileNames -> A " << endl;
    Wait();  
    cout << "[DEBUG] ReadFileNames -> B " << endl;


    // read filename stuff
}

void Upload::Wait()
{
    typedef boost::chrono::duration<long, boost::ratio<60> > seconds;
    int randomWaitTime = 0;
    try{   
        randomWaitTime = lexical_cast<unsigned int>(getId());
        randomWaitTime = randomWaitTime * 10;
    }
    catch ( const boost::bad_lexical_cast & e){
        // cout << "[LOG] FileUpLoad : Wait : bad_lexical_cast : "  << e.what() << endl ;
        randomWaitTime = 0;
    }

    seconds testTimeToWait(randomWaitTime);

    cout << "[DEBUG] Wait() -> A" << endl;
    boost::this_thread::sleep_for(testTimeToWait);
    cout << "[DEBUG] Wait() -> B" << endl;

    cout << "RANDOM WAIT TIME = " << randomWaitTime << endl;
}

main.cpp

int  main()
{   
    pthread_t threadA; 
    pthread_create(&threadA,NULL,threadAfn,NULL);

    pthread_t threadB;
    pthread_create(&threadB,NULL,threadBfn,NULL);

    pthread_t Upload;    //  <--- Thread in question
    pthread_create(&Upload,NULL,Uploadfn,NULL);

    pthread_join(threadA,NULL);
    pthread_join(threadB,NULL);
    pthread_join(Upload,NULL); // <--- Thread in question

    return 0; 
}

输出
[DEBUG] ReadFileNames -> A 
[DEBUG] Wait() -> A
// hangs here and rest of the threads are locked/slept as well?

最佳答案

it hangs there and sleeps all the other threads as well



不,不是。如果那样似乎是,那是因为其他线程已经卡住或结束。

查找阻塞的事物(mutex.lock,条件等待,IO操作等)或检查线程是否未退出。

笔记
  • 您的seconds计算已关闭。在我的系统上,以下内容:

    Live On Coliru
    #include <boost/chrono.hpp>
    #include <iostream>
    
    int main() {
        std::cout << boost::chrono::duration<long, boost::ratio<60> >(1)/boost::chrono::seconds(1) << std::endl;
    }
    

    版画
    60
    

    因此,您命名的seconds实际上是几分钟。只需这样做:
    using boost::chrono::seconds;
    int delay = std::strtoul(getId().c_str(), NULL, 10)*10;
    sleep_for(seconds(delay));
    
  • 如果getId返回是,则您的随机延迟是随机的。使用boost/random.hpp,可以通过良好的范围控制使其真正随机化。例如。休眠1000到3000毫秒之间:

    int random_gen(int low,int high){//不是线程安全的
    静态boost::random_device rdev;
    静态升压:: mt19937 prng(rdev);
    返回boost::uniform_int <>(low,high)(prng);
    }

    无效上传:: Wait(){
    int const ms_delay = random_gen(1000,3000);
    cout <<“RANDOM WAIT TIME =” << ms_delay << endl;
    sleep_for(毫秒(ms_delay));
    }

    Note to seed using random_device as shown (so true random seed) you need to link the random library. Otherwise, you can "stoop" to a time-based seed:

     static boost::mt19937 prng(std::time(NULL));
    

  • 这是代码的独立版本,其中应用了各种建议,表明没有死锁/软锁:

    Live On Coliru
    #include <boost/asio.hpp>
    #include <boost/chrono.hpp>
    #include <boost/lexical_cast.hpp>
    #include <boost/thread.hpp>
    #include <iostream>
    #include <boost/random.hpp>
    
    using boost::this_thread::sleep_for;
    using boost::chrono::seconds;
    using boost::chrono::milliseconds;
    
    using boost::lexical_cast;
    using std::cout;
    using std::endl;
    
    struct Upload {
        std::string getId() const { return "42"; }
        void Wait();
        void ReadFileNames();
    };
    
    void Upload::ReadFileNames() {
        cout << "[DEBUG] ReadFileNames -> A " << endl;
        Wait();
        cout << "[DEBUG] ReadFileNames -> B " << endl;
    
        // read filename stuff
    }
    
    int random_gen(int low, int high) { // not threadsafe
        static boost::mt19937 prng(std::time(NULL));
        return boost::uniform_int<>(low, high)(prng);
    }
    
    void Upload::Wait() {
        int const ms_delay = random_gen(1000, 3000);
        cout << "RANDOM WAIT TIME = " << ms_delay << endl;
        sleep_for(milliseconds(ms_delay));
    }
    
    void background(char const* name) {
        // desync different background threads
        sleep_for(milliseconds(boost::hash_value(name) % 1000));
    
        for (int i=0; i<5; ++i) {
            sleep_for(seconds(1));
            std::clog << name << " " << i << std::endl;
        }
    }
    
    void threadAfn() { background("thread A"); }
    void threadBfn() { background("thread B"); }
    
    void Uploadfn() {
        Upload u;
        u.ReadFileNames();
    }
    
    int main() {
        boost::thread threadA(threadAfn);
        boost::thread threadB(threadBfn);
        boost::thread Upload(Uploadfn);
    
        threadA.join();
        threadB.join();
        Upload.join();
    }
    

    打印品,例如:
    [DEBUG] ReadFileNames -> A 
    RANDOM WAIT TIME = 1150
    [DEBUG] ReadFileNames -> B 
    thread A 0
    thread B 0
    thread A 1
    thread B 1
    thread A 2
    thread B 2
    thread A 3
    thread B 3
    thread A 4
    thread B 4
    

    关于c++ - boost::this_thread::sleep_用于使整个程序休眠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62440698/

    相关文章:

    c++11 shared_ptr + Boost::序列化

    C++ 默认参数乱序?

    c++ - 如何通过带参数构造来使用私有(private)继承?

    C++ 继承 - 从构造函数调用重写

    具有线程安全队列的 C++11 事件循环

    java - 尽管可读,选择器仍不活动

    c++ - 编译Boost时如何更改/检查b2使用的编译器?

    c++ - 模板化递归函数的语法是什么?

    java - 等待/通知死锁

    c++ - 如何使用 boost 将流放入缓冲区