我正在寫一個程序在C++中,我需要定期調用一個函數,每隔10ms左右調用一個函數。我從來沒有做過任何與C++中的時間或時鐘相關的任何事情,這是一個快速簡單的問題還是其中沒有完整解決方案的問題?需要定期調用一個函數在c + +中
謝謝!
我正在寫一個程序在C++中,我需要定期調用一個函數,每隔10ms左右調用一個函數。我從來沒有做過任何與C++中的時間或時鐘相關的任何事情,這是一個快速簡單的問題還是其中沒有完整解決方案的問題?需要定期調用一個函數在c + +中
謝謝!
你可以看看線程:
下面是C,實施使用pthread.h的時間間隔控制功能,它應該是一個簡單的端口C++。 Executing a function at specific intervals
一個簡單的定時器可以實現如下,
#include <iostream>
#include <chrono>
#include <thread>
#include <functional>
void timer_start(std::function<void(void)> func, unsigned int interval)
{
std::thread([func, interval]() {
while (true)
{
func();
std::this_thread::sleep_for(std::chrono::milliseconds(interval));
}
}).detach();
}
void do_something()
{
std::cout << "I am doing something" << std::endl;
}
int main() {
timer_start(do_something, 1000);
while(true);
}
這種簡單的解決方案並沒有提供一種方法來停止計時器。計時器將繼續運行,直到程序退出。
很酷,我也學習如何通過這個例子創建一個新的線程。 – 123iamking
@ user534498不幸的是,你的解決方案不會做他所問的。它會在兩次調用之間用'interval'延遲執行'func'。它不會每'間隔'執行'func'。如果'func'可能需要一段時間才能運行,則啓動時間也會有所不同。 – ilya1725
這取決於你將在每個區間做什麼 - 在屏幕/窗體的特定位置顯示時間/代碼或其他內容。或者您可能需要將常規數據發送到某個連接的機器(通過套接字或管道)。你真的需要10毫秒的精度嗎?
根據要求,特別是精度要求,你可能有專門的線程做'東西',然後等待,再做同樣的事情。或者,在Windows上,您可以使用SetTimer
在每個時間間隔觸發WM_TIMER
事件(它不需要線程)。你也可以使用等待定時器,多媒體定時器等。
最後,但相當重要 - 你需要平臺和編譯器的兼容性嗎?意思是說,你將使用哪種操作系統,還是你需要平臺獨立?您正在尋找哪些編譯器功能(C++ 11,C++ 14或pre C++ 11)。
如果你使用Visual C++編碼,你可以添加一個計時器元素到你想要調用周期函數的表單中(這裏叫做我的表單是MainForm
,我的計時器是MainTimer
)。在「事件」中添加對tick事件的調用。設計師將在您的.h文件中添加這樣一行:
this->MainTimer->Enabled = true;
this->MainTimer->Interval = 10;
this->MainTimer->Tick += gcnew System::EventHandler(this, &MainForm::MainTimer_Tick);
然後,在每個時間間隔(以毫秒爲單位指定),應用程序將調用這個函數
private: System::Void MainTimer_Tick(System::Object^ sender, System::EventArgs^ e) {
/// Enter your periodic code there
}
注意:這是C++/CLI代碼而不是標準C++。 – crashmstr
要完成的問題,代碼從@ user534498可以很容易地適應有周期性的時間間隔。 只需確定計時器線程循環開始時的下一個開始時間點,並在執行該函數後確定該時間點。
#include <iostream>
#include <chrono>
#include <thread>
#include <functional>
void timer_start(std::function<void(void)> func, unsigned int interval)
{
std::thread([func, interval]()
{
while (true)
{
auto x = std::chrono::steady_clock::now() + std::chrono::milliseconds(interval);
func();
std::this_thread::sleep_until(x);
}
}).detach();
}
void do_something()
{
std::cout << "I am doing something" << std::endl;
}
int main()
{
timer_start(do_something, 1000);
while (true)
;
}
這是正確的方法,只要注意'func()'必須在'sleep_until'結束之前完成! –
對不起,但我沒有找到比這更簡單的設計。
你可以,讓擁有兩個線程類,以及weak_ptr
本身, 是一個「支架」的可調用可以放心地看到它,因爲即使該對象被破壞的可調用 將依然存在。你不想要一個懸掛指針。
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;
}
''有這種支持。 –
chris