Reputation: 11
i have spend a lot of time for it but i cant find the right way to do it. I want a function thats called every x minutes to do over stuff, but without stopping my whole program. It's just a function in a large program. I have tried a lot of functions like difftime or others, but everything stops my program and difftime does not work for me, like this one
void ProcStatistics(int thisarg)
time_t end;
time(&start);
while (1) {
time(&end);
double dif = difftime (end,start);
if (dif < 600)
{
std::cout << "Start" << std::endl;
//do other stuff
std::cout << "End" << std::endl;
time(&end);
return detour_ProcStatistics->GetOriginalFunction()(thisarg);
}
I cant use sleep, maybe a loop or something else, with a break or continue. The problem is that program time constantly updated, because it runs all the time.
Upvotes: 1
Views: 236
Reputation: 422
The code below would work better than anything using sleep_for
if maintaining timing is critical. If you're not sweating the microseconds, (picoseconds?) then Trevor's answer is a lot simpler.
Uses C++11 features. Must be linked with -lpthread if using g++ (at least for mine) Runs as written to give a simple and easy to understand demonstration
#include <chrono>
#include <thread>
#include <iostream>
//This is where you set the rate to call repeated_function at
constexpr int ancilary_function_rate_minutes = 3;
//This is the function which will be called repeatedly
void repeated_function(void)
{
//TODO: Put useful code here
//TODO: Be aware of race conditions, use std::mutex variables to guard conflicts
//This code should be discarded for actual use, but makes a reasonable demonstration
static int i = 0;
std::cout << __PRETTY_FUNCTION__ << " " << i << std::endl;
i++;
return;
}
void ancilary_thread_main(void)
{
std::chrono::system_clock::time_point tp =
std::chrono::system_clock::now();
while(1)
{
//use the below line for minutes for intended application
//tp += std::chrono::minutes(ancilary_function_rate_minutes);
//use the below line for seconds to see it run in realtime
tp += std::chrono::seconds(3);
//Note the above two durations are additive, you could use both
repeated_function(); //This is where the function gets called repeatedly
//By using sleep_until instead of sleep_for, and by only calling now()
// once, we do not lose the time it takes to run repeated_function and
// allow our rate to drift
std::this_thread::sleep_until(tp);
//Note that this will sleep AT LEAST until the given time, there is no
// guarantee that it will run then, but more likely will run the first
// time after that when a processor (core) becomes available.
}
}
int main()
{
//First launch the initial thread
std::thread my_thread (ancilary_thread_main);
//The rest of your code here
//This code should be discarded for actual use, but makes a reasonable demonstration
int i = 0;
while(1) //Generally only acceptable in embedded applications
{
std::cout << "Main Thread " << i << std::endl;
i++;
//Because this look uses sleep_for, it will lose time over many iterations
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
my_thread.join(); //This is unreachable, but in application, main loop will eventually exit.
return 0;
}
Upvotes: 0
Reputation: 11
I think you are right, i have read about threads, but I dont really know how I can use it for this program. Maybe you can make a solution for me. Small snippet from main.ccp:
int AffAddPoint(int a1, int a2, int a3)
{
#ifdef TEST
std::cout << "(int)Points: " << (int)a2 << std::endl;
std::cout << "(LONGLONG)Points: " << (LONGLONG)a2 << std::endl;
#endif
detour_affinity->GetOriginalFunction()(a1, a2, a3);
}
// Function what i need ->
void ProcStatistics(int thisarg)
{
{
std::cout << "Start" << std::endl;
char const* godbless = " 410 5";
((void(*)(int, char const*))0x082249E4)(0, godbless);
godbless = " 627 4";
std::cout << "End" << std::endl;
}
return detour_ProcStatistics->GetOriginalFunction()(thisarg);
}
// <- Function End
detour_ProcStatistics = simpleHook<tProcStatistics>((unsigned int)0x081E3934, ProcStatistics);
void ConnectDB()
{
mysql_init(&m_dbuserxx);
small snippet from main.h
typedef void (*tProcStatistics)(int);
MologieDetours::Detour<tProcStatistics>* detour_ProcStatistics= NULL;
Upvotes: 0
Reputation: 37806
Please note, this is C+11 and above.
#include <chrono>
#include <thread>
//spawn a new thread as to not stop the whole program.
std::thread t([] {
//call a function every n minutes
while (1){
std::this_thread::sleep_for(std::chrono::minutes(/*n minutes*/));
function();
}
});
//thread can now run in background,
//and you don't have to worry about joining it.
//i.e. a terminate call without an active exception
t.detach();
Upvotes: 1