创建一个计时器在X秒内调用一个函数
Create a Timer to call a function in X Seconds
我有一个打印函数,我想在5秒内执行。问题是我想要函数中其他的东西。例如,如果我的代码是:
// insert code here...
printf("(5 seconds later) Hello"); /* should be executed in 5 seconds */
printf("heya");
以main函数为例。现在是棘手的部分。虽然第一行应该在5秒内执行,但如果第一行根本不存在,第二行应该像正常一样执行。因此输出将是:
heya
(5 seconds later) Hello
如果你熟悉Cocoa或Cocoa Touch,这就是NSTimer类的工作方式。使用c++,有没有比使用线程更简单或内置的方法?如果没有,我该如何使用多线程来实现这一点呢?
使用<chrono>
和<thread>
,您可以创建一个非常基本的,但很简单的:
std::thread printLater{[] {
std::this_thread::sleep_for(std::chrono::seconds(5));
printf("(5 seconds later) Hello");
}};
printf("heya");
printLater.join(); //when you want to wait for the thread to complete
Pubby指出的另一个方法是使用std::async
:
,该方法具有自动等待线程完成并且在抛出异常时不停止的优点。auto f = std::async(std::launch::async, [] {
std::this_thread::sleep_for(std::chrono::seconds(5));
printf("(5 seconds later) Hello");
});
printf("heya");
将std::async
存储到变量中的结果意味着调用将启动一个新线程来运行该函数。如果不存储结果,就不会有新的线程。这是语言中的一个新问题。
注意,如果在每个线程中打印不止一个东西,那么它可能不会精确地在5秒后打印,并且没有同步输出,因此您可能会得到交错的输出块(printf
是原子的,因此每个调用的整个输出将交错)。如果没有同步,就不能保证哪些语句在什么时候发生,因此如果您确实需要注意可能出现的同步问题,就应该小心。但是,对于基本目的,这应该可以工作。
我是这样解决这个问题的:
#include <iostream>
#include <thread>
#include <chrono>
std::thread timerThread;
void printStatement() {
std::this_thread::sleep_for(std::chrono::seconds(5));
printf("(5 seconds later) Hello");
}
bool myBool() {
timerThread = std::thread(printStatement);
return YES;
}
int main(int argc, const char * argv[])
{
// insert code here...
printf("%in", myBool());
printf("heyan");
// you could also use the async stuff, join or std::future instead of sleep()
sleep(5); // this is only here to keep the thread from being detatched before it can even finish sleeping
timerThread.detach();
return 0;
}
我的snap版本与boost asio和std::async。
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/noncopyable.hpp>
#include <chrono>
#include <future>
#include <memory>
#include <iostream>
class MonotonicExecutor
: public boost::noncopyable,
public std::enable_shared_from_this<MonotonicExecutor> {
typedef std::function<void()> Functor;
public:
MonotonicExecutor(boost::posix_time::time_duration trig)
: m_service(),
m_serviceWork(
std::make_shared<boost::asio::io_service::work>(m_service)),
m_deadlineTimer(m_service), m_trigger(trig) {
auto fut = std::async(std::launch::async, [&]() { m_service.run(); });
fut.wait_for(std::chrono::milliseconds(1));
}
void executeAsync(Functor fun) {
m_deadlineTimer.expires_from_now(m_trigger);
m_deadlineTimer.async_wait(std::bind(&MonotonicExecutor::execute,
shared_from_this(),
std::placeholders::_1, fun));
}
void abort() { m_deadlineTimer.cancel(); }
private:
void execute(const boost::system::error_code &err, Functor fun) {
if (err != boost::asio::error::operation_aborted &&
m_deadlineTimer.expires_at() <=
boost::asio::deadline_timer::traits_type::now()) {
m_deadlineTimer.cancel();
fun();
m_deadlineTimer.expires_from_now(m_trigger);
m_deadlineTimer.async_wait(std::bind(&MonotonicExecutor::execute,
shared_from_this(),
std::placeholders::_1, fun));
}
}
private:
boost::asio::io_service m_service;
std::shared_ptr<boost::asio::io_service::work> m_serviceWork;
boost::asio::deadline_timer m_deadlineTimer;
boost::posix_time::time_duration m_trigger;
};
int main(int argc, char *argv[]) {
auto executor =
std::make_shared<MonotonicExecutor>(boost::posix_time::seconds(3));
executor->executeAsync([&]() {
std::cout << boost::posix_time::to_iso_string(
boost::posix_time::second_clock::local_time())
<< std::endl;
});
auto stop = std::chrono::system_clock::now() + std::chrono::seconds(30);
while (std::chrono::system_clock::now() < stop) {
std::this_thread::sleep_for(std::chrono::seconds(1));
}
executor->abort();
std::cout << "Wait and see if the task is aborted" << std::endl;
stop = std::chrono::system_clock::now() + std::chrono::seconds(30);
while (std::chrono::system_clock::now() < stop) {
std::this_thread::sleep_for(std::chrono::seconds(1));
}
return 0;
}
相关文章:
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 构造函数正在调用一个使用当前类类型的函数
- 我不小心调用了一个没有自己类对象的成员函数.但这是怎么回事呢
- 在另一个线程中调用luaL_error会引发qWarning
- 如何在qt中从另一个类调用函数
- 检查哪个对象调用了另一个对象的对象方法
- GLEW/GLUT:调用init并创建一个窗口后,取消初始化并重新初始化?
- 我有一个调用ID3D11DeviceContext::CopySubresourceRegion的循环.我怎么能强制等待
- 当另一个调用 lambda 使用默认捕获时,lambda 的闭包可能会被破坏吗?
- 在C++中嵌入Python:在Python脚本中导入模块在一个函数调用过程中有效,但在另一个调用过程中无效
- 如何在一个调用中释放多个互斥对象
- 我希望计时器只在上一个调用返回或完成执行时调用代码
- 定义一个调用其他函数的内联函数是否有意义
- 我如何测试一个调用是在谷歌测试延迟后使用嘲讽框架进行的
- 我想创建一个调用函数的源文件,而不必创建对象
- 是否有可能制作一个调用jdbc的Java JNI
- 如果您有一个调用其他内部函数的类接口函数
- 打开文件来自一个调用请求在黑莓10级联
- 创建一个调用另一个可执行文件的可执行文件
- 什么是崩溃我的应用程序的异常,给定一个调用堆栈与UnhandledExceptionFilter