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

boost::this_thread::sleep_for sleeping entire program

本文关键字:程序 sleep this thread boost for      更新时间:2023-10-16

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;
}

主.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?

它挂在那里,也休眠所有其他线程

不,它没有。如果看起来是这样,那是因为其他线程已经卡住或完成。

查找阻塞的内容(mutex.lock、条件等待、IO 操作等(或检查线程是否未退出。

笔记

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

    住在科里鲁

    #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时,您的随机延迟才是随机的。使用boost/random.hpp,您可以使其真正随机,并具有良好的范围控制。例如,睡眠时间在 1'000 到 3'000 毫秒之间:

    int random_gen(int low, int high( {//not threadsafe 静态升压::random_device RDev; 静态升压::MT19937 PRNG(RDvDer(; 返回助推::uniform_int<>(低,高((PRNG(; }

    void 上传::等待(( { int const ms_delay = random_gen(1000, 3000(; cout <<"随机等待时间 = " <<ms_delay <<endl; sleep_for(毫秒(ms_delay((; }

    请注意,如图所示使用random_device进行种子(因此是真正的随机种子(,您需要链接随机库。否则,您可以"屈服"到基于时间的种子:

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

下面是应用了各种建议的代码的独立版本,演示没有死锁/软锁:

住在科里鲁

#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