在 C++ 中停止周期性线程
Stopping a periodic thread-thing in c++
所以我有这个函数,它的行为类似于 JS 中的 setInterval 函数。我找到了 here。
我目前正在尝试更改它以便可以将其停止。我不完全理解这段代码的行为。
void setInterval(function<void(void)> func, unsigned int interval) {
thread([func, interval]() {
while (1) {
auto x = chrono::steady_clock::now() + chrono::milliseconds(interval);
func();
this_thread::sleep_until(x);
}
}).detach();
}
我这样试过:
void setInterval(function<void(void)> func, unsigned int interval, bool &b) {
thread([func, interval, *b]() {
while (*b) {
auto x = chrono::steady_clock::now() + chrono::milliseconds(interval);
func();
this_thread::sleep_until(x);
}
}).detach();
}
(这不会编译),主要是这样调用它:
bool B;
setInterval(myFunction,1000,B);
我原以为如果我将 B 变量更改为 false,那么 setInterval 函数中的线程就会停止,但我并没有像这样达到我的目标。有 idead/suggestions 吗?提前谢谢你。
抱歉,我没有找到比这更简单的设计。
你可以创建一个 class 既拥有一个线程,又拥有一个 weak_ptr
给自己,
成为可调用对象可以安全看到它的 "holder",因为可调用对象
即使对象被破坏,它仍然存在。你不需要悬空指针。
template<typename T>
struct IntervalRepeater {
using CallableCopyable = T;
private:
weak_ptr<IntervalRepeater<CallableCopyable>> holder;
std::thread theThread;
IntervalRepeater(unsigned int interval,
CallableCopyable callable): callable(callable), interval(interval) {}
void thread() {
weak_ptr<IntervalRepeater<CallableCopyable>> holder = this->holder;
theThread = std::thread([holder](){
// Try to strongify the pointer, to make it survive this loop iteration,
// and ensure that this pointer is valid, if not valid, end the loop.
while (shared_ptr<IntervalRepeater<CallableCopyable>> ptr = holder.lock()) {
auto x = chrono::steady_clock::now() + chrono::milliseconds(ptr->interval);
ptr->callable();
this_thread::sleep_until(x);
}
});
}
public:
const CallableCopyable callable;
const unsigned int interval;
static shared_ptr<IntervalRepeater<T>> createIntervalRepeater(unsigned int interval,
CallableCopyable callable) {
std::shared_ptr<IntervalRepeater<CallableCopyable>> ret =
shared_ptr<IntervalRepeater<CallableCopyable>>(
new IntervalRepeater<CallableCopyable>(interval, callable));
ret->holder = ret;
ret->thread();
return ret;
}
~IntervalRepeater() {
// Detach the thread before it is released.
theThread.detach();
}
};
void beginItWaitThenDestruct() {
auto repeater = IntervalRepeater<function<void()>>::createIntervalRepeater(
1000, [](){ cout << "A second\n"; });
std::this_thread::sleep_for(std::chrono::milliseconds(3700));
}
int main() {
beginItWaitThenDestruct();
// Wait for another 2.5 seconds, to test whether there is still an effect of the object
// or no.
std::this_thread::sleep_for(std::chrono::milliseconds(2500));
return 0;
}
C++不是JavaScript,但C++可以应用不同语言的大部分编程范式。
所以我有这个函数,它的行为类似于 JS 中的 setInterval 函数。我找到了 here。 我目前正在尝试更改它以便可以将其停止。我不完全理解这段代码的行为。
void setInterval(function<void(void)> func, unsigned int interval) {
thread([func, interval]() {
while (1) {
auto x = chrono::steady_clock::now() + chrono::milliseconds(interval);
func();
this_thread::sleep_until(x);
}
}).detach();
}
我这样试过:
void setInterval(function<void(void)> func, unsigned int interval, bool &b) {
thread([func, interval, *b]() {
while (*b) {
auto x = chrono::steady_clock::now() + chrono::milliseconds(interval);
func();
this_thread::sleep_until(x);
}
}).detach();
}
(这不会编译),主要是这样调用它:
bool B;
setInterval(myFunction,1000,B);
我原以为如果我将 B 变量更改为 false,那么 setInterval 函数中的线程就会停止,但我并没有像这样达到我的目标。有 idead/suggestions 吗?提前谢谢你。
抱歉,我没有找到比这更简单的设计。
你可以创建一个 class 既拥有一个线程,又拥有一个 weak_ptr
给自己,
成为可调用对象可以安全看到它的 "holder",因为可调用对象
即使对象被破坏,它仍然存在。你不需要悬空指针。
template<typename T>
struct IntervalRepeater {
using CallableCopyable = T;
private:
weak_ptr<IntervalRepeater<CallableCopyable>> holder;
std::thread theThread;
IntervalRepeater(unsigned int interval,
CallableCopyable callable): callable(callable), interval(interval) {}
void thread() {
weak_ptr<IntervalRepeater<CallableCopyable>> holder = this->holder;
theThread = std::thread([holder](){
// Try to strongify the pointer, to make it survive this loop iteration,
// and ensure that this pointer is valid, if not valid, end the loop.
while (shared_ptr<IntervalRepeater<CallableCopyable>> ptr = holder.lock()) {
auto x = chrono::steady_clock::now() + chrono::milliseconds(ptr->interval);
ptr->callable();
this_thread::sleep_until(x);
}
});
}
public:
const CallableCopyable callable;
const unsigned int interval;
static shared_ptr<IntervalRepeater<T>> createIntervalRepeater(unsigned int interval,
CallableCopyable callable) {
std::shared_ptr<IntervalRepeater<CallableCopyable>> ret =
shared_ptr<IntervalRepeater<CallableCopyable>>(
new IntervalRepeater<CallableCopyable>(interval, callable));
ret->holder = ret;
ret->thread();
return ret;
}
~IntervalRepeater() {
// Detach the thread before it is released.
theThread.detach();
}
};
void beginItWaitThenDestruct() {
auto repeater = IntervalRepeater<function<void()>>::createIntervalRepeater(
1000, [](){ cout << "A second\n"; });
std::this_thread::sleep_for(std::chrono::milliseconds(3700));
}
int main() {
beginItWaitThenDestruct();
// Wait for another 2.5 seconds, to test whether there is still an effect of the object
// or no.
std::this_thread::sleep_for(std::chrono::milliseconds(2500));
return 0;
}
C++不是JavaScript,但C++可以应用不同语言的大部分编程范式。