英文:
std::thread dosnt dosnt excute funtion c++
问题
这是您提供的代码的翻译部分:
我有这个简单的函数:
class Timer {
std::atomic<bool> active{true};
public:
void setInterval(auto function, int interval);
void stop();
};
void Timer::setInterval(auto function, int interval) {
active = true;
std::thread t([=]() {
while(active.load()) {
std::this_thread::sleep_for(std::chrono::milliseconds(interval));
if(!active.load()) return;
function();
}
});
t.detach();
}
void Timer::stop() {
active = false;
}
现在当我尝试运行它:
int main()
{
printf("start\n");
Timer* timer = new Timer();
timer->setInterval([&]() {
std::cout << "hello" << std::endl;
}, 1000);
return 0;
};
仅从主类中打印开始,它从未到达setInterval函数内的function(); 它只是停止了应用程序,没有错误。
编译/链接命令:
/usr/bin/g++ -fdiagnostics-color=always -std=c++14 -pthread -g /home/vagrant/cpp/batch/main.cpp -o /home/vagrant/cpp/batch/main
英文:
i have this simple function :
class Timer {
std::atomic<bool> active{true};
public:
void setInterval(auto function, int interval);
void stop();
};
void Timer::setInterval(auto function, int interval) {
active = true;
std::thread t([=]() {
while(active.load()) {
std::this_thread::sleep_for(std::chrono::milliseconds(interval));
if(!active.load()) return;
function();
}
});
t.detach();
}
void Timer::stop() {
active = false;
}
Now when i try to run it :
int main()
{
printf("start\n");
Timer* timer = new Timer();
timer->setInterval([&]() {
std::cout << "hello" << std::endl;
},1000);
return 0;
};
Only the start printed from the main class , its never reach the function(); inside the
setInterval function its just stops the app with no error .
the compile/link command :
/usr/bin/g++ -fdiagnostics-color=always -std=c++14 -pthread -g /home/vagrant/cpp/batch/main.cpp -o /home/vagrant/cpp/batch/main
答案1
得分: 2
这是正确使用线程对象来运行计时器的众多方法之一。
#include <atomic>
#include <thread>
#include <chrono>
#include <iostream>
class Timer {
private:
std::atomic<bool> active = false;
std::unique_ptr<std::thread> timer_thread;
public:
// 这个类需要一个析构函数。
~Timer()
{
stop();
}
// 这个函数名字有误导性,
// void setInterval(auto function, int interval);
//
// 让我们将其重命名为它实际做的事情,还要尽量将函数参数放在最后,
// 这样在使用lambda表达式调用时,代码更易读。
//
// 你不知道 'cb',调用者的可调用对象是可复制还是可移动的,所以应该使用完美
// 转发,这仅在模板中( readily)可用。
template <typename Fn>
void start(int interval, Fn&& cb)
{
stop(); // 确保我们停止了。
active = true;
// 启动线程,回调对象的 forward<> 是重要的!
timer_thread = std::make_unique<std::thread>(
[this, ms = std::chrono::milliseconds(interval), cb = std::forward<Fn>(cb)]() {
while (active) // 调用 atomic<>::load() 自动完成
{
std::this_thread::sleep_for(ms);
if (active)
cb();
}
});
}
// 这是我们终止线程并等待它退出的地方。
void stop()
{
active = false;
if (timer_thread)
{
timer_thread->join();
timer_thread.reset();
}
}
bool isRunning() const
{
return active;
}
};
int main()
{
std::cout << "start\n";
Timer timer; // 绝对没有必要将计时器放在堆上。
int n = 4; // 一个简单的倒计时示例,直到1。
timer.start(1000, [&]() {
std::cout << "countdown: " << n << '\n';
if (--n <= 0)
timer.stop();
});
// 在退出程序之前,我们应该等待计时器停止。
while (timer.isRunning()) {}
return 0;
};
请注意,上述代码是使用C++编写的,用于创建一个简单的计时器。如果您需要进一步的解释或有其他问题,请随时提出。
英文:
Here is one of the many ways of correctlty using a thread object to run your timer.
#include <atomic>
#include <thread>
#include <chrono>
#include <iostream>
class Timer {
private:
std::atomic<bool> active = false;
std::unique_ptr<std::thread> timer_thread;
public:
// this class needs a destructor.
~Timer()
{
stop();
}
// this function name is misleading,
// void setInterval(auto function, int interval);
//
// let's rename it to what it does, also try to keep
// the function argument last, this makes the code
// more legible when calling with a lambda.
//
// you do not know if 'cb', the caller's callable object
// is copyable or moveable, so you should use perfect
// forwarding, that's only (readily) available from a
// template.
template <typename Fn>
void start(int interval, Fn&& cb)
{
stop(); // make sure we're stopped.
active = true;
// start the thread, the forward<> of the callback object is
// important!
timer_thread = std::make_unique<std::thread>(
[this, ms = std::chrono::milliseconds(interval), cb = std::forward<Fn>(cb)]() {
while (active) // calls atomic<>::load() automatically
{
std::this_thread::sleep_for(ms);
if (active)
cb();
}
});
}
// this is where we kill the thread, and wait for it to exit.
void stop()
{
active = false;
if (timer_thread)
{
timer_thread->join();
timer_thread.reset();
}
}
bool isRunning() const
{
return active;
}
};
int main()
{
std::cout << "start\n";
Timer timer; // There's absolutely no need to place timer on the heap.
int n = 4; // simple countdown to 1 for example.
timer.start(1000, [&]() {
std::cout << "countdown: " << n << '\n';
if (--n <= 0)
timer.stop();
});
// We should wait for the timer to stop, before exiting the program.
while (timer.isRunning()) {}
return 0;
};
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论