boost::this_thread::sleep_for 休眠整个程序

boost::this_thread::sleep_for sleeping entire program

C++98 和 Boost 1.54

我无法弄清楚为什么使用 boost::this_thread::sleep_for 会使我的整个程序休眠。调用 Wait() 函数的唯一时间和地点是在该线程内,该线程的唯一目的是读取目录中的文件名并触发上传。

但由于某种原因,当它到达 Wait() 函数中的 boost::this_thread::sleep_for 行时,它挂在那里并使所有其他线程也休眠。我不确定我错过了什么,所以任何帮助将不胜感激。

代码:

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 操作等)或检查线程是否退出。

备注

  1. 您的 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));
    
  2. 你的随机延迟只有在 getId return 是随机的情况下才是随机的。使用 boost/random.hpp 你可以让它真正随机,并有很好的范围控制。例如。在 1'000 到 3'000 毫秒之间休眠:

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

    无效Upload::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));
    

这是您的代码的独立版本,应用了各种建议,表明没有 deadlock/softlock:

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