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 操作等)或检查线程是否退出。
备注
您的 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));
你的随机延迟只有在 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:
#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++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 操作等)或检查线程是否退出。
备注
您的
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));
你的随机延迟只有在
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:
#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