Można np. tak:
#include <iostream>
#include <thread>
#include <chrono>
#include <string>
void worker(const std::string& msg) {
std::cout << "Uruchomienie funkcji z parametrem: " << msg << std::endl;
}
void incrementer(int& value) {
++value;
}
template<typename Function, typename... Args>
void cycle_run(std::chrono::seconds dur, Function func, Args&&... args) {
using namespace std::chrono;
system_clock::time_point next_run = system_clock::now()
+ dur;
for(;;) {
std::this_thread::sleep_until(next_run);
func(std::forward<Args>(args)...);
next_run += dur;
}
}
int main() {
// Jakaś zmienna do testu.
int value = 0;
// Komunikat co 1 sekundę.
auto period = std::chrono::seconds(1);
// Przykład 1 i 2. Aby sprawdzić czy rozwiązanie (w miarę) uniwersalne.
auto thr1 = std::thread([&]{ cycle_run(period, worker, "abrakadabra"); });
auto thr2 = std::thread([&]{ cycle_run(period, incrementer, std::ref(value)); });
thr1.detach();
thr2.detach();
// Wykona 10 pętli wyświetlając wartość zmiennej w odstępach co 0.5 sekundy.
for(auto i = 0; i < 10; ++i) {
std::cout << "value = " << value << '\n';
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
}
Ale jeśli masz coś zwrócić z funkcji, lepsze będzie std::future. Najprościej wtedy użyć std::async.