C++ calling a method in specified interval without sleep - c++

I need to execute multiple methods with specified interval(1 millisecond). Is there any way to call the methods in a loop without sleep because I am not getting 1000 entries in a log file for a second
Currently I have implemented using sleep. Data collection also might take little time.
#include <iostream>
#include <string>
#include <unordered_map>
#include <functional>
#include <csignal>
#include <chrono>
#include <thread>
#include <fstream>
#include <ctime>
#include <iomanip>
#include <sstream>
#include <windows.h>
#include <atomic>
volatile std::sig_atomic_t gStatus{};
void signalHandler(int sig) {
gStatus = sig;
}
void feature1(std::string &output) { output = "feature1"; }
void feature2(std::string &output) { output = "feature2"; }
void feature3(std::string &output) { output = "feature3"; }
void feature4(std::string &output) { output = "feature4"; }
void feature5(std::string &output) { output = "feature5"; }
void feature6(std::string &output) { output = "feature6"; }
void processInfoRequest(std::string logFile, std::unordered_map<std::string, std::function<void(std::string &value)>> methodMap)
{
std::ofstream ofs(logFile);
std::uint64_t prevTime = 0, curTime = 0, diffTime = 0, tmpTime = 0, scheduleTime = 0, pollPeriod = 1;
prevTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
while (gStatus != SIGINT)
{
prevTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
prevTime = prevTime - scheduleTime;
**//get value**
auto timenow = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
ofs << ctime(&timenow);
for(auto it : methodMap)
{
std::string output;
it.second(output);
ofs << output << ",";
}
ofs << "\n";
curTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
diffTime = curTime - prevTime;
if (diffTime < pollPeriod)
{
diffTime = pollPeriod - diffTime;
curTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
std::uint64_t i = 0;
std::uint64_t n = diffTime / 10;
std::uint64_t remainingMs = diffTime % 10;
for (i = 0; i < n; i++)
{
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
std::this_thread::sleep_for(std::chrono::milliseconds(remainingMs));
tmpTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
scheduleTime = tmpTime - (curTime + diffTime);
}
else
{
scheduleTime = 0;
}
}
ofs.close();
}
int main()
{
std::signal(SIGINT, signalHandler);
std::string output;
std::unordered_map<std::string, std::function<void(std::string &value)>> methodMap = {
{"f1", feature1},
{"f2", feature2},
{"f3", feature3},
{"f4", feature4},
{"f5", feature5},
{"f6", feature6}
};
std::thread th1 = std::thread(processInfoRequest, "threadlog.csv", methodMap);
if (th1.joinable())
th1.join();
return 0;
}

Related

How to benchmark my system using multiple threads in c++?

I have simplified my code, and it compiles, but it doesn't do anything. It doesn't error out though either. I am trying to get 7 threads (on my 8-core processor) in this example to write to a variable to benchmark my system. I would like to do this with multiple threads to see if it's faster. It's based off other code that worked before I added multithreading. When I run, it just terminates. It should show progress each second of how many total iterations all the threads have done together. Some of the includes are there from other code I am working on.
I would like to also gracefully terminate all 7 threads when Ctrl-C is pressed. Help would be appreciated. Thanks!
//Compiled using: g++ ./test.cpp -lpthread -o ./test
#include <stdio.h>
#include <string>
#include <iostream>
#include <time.h>
#include <ctime>
#include <ratio>
#include <chrono>
#include <iomanip>
#include <locale.h>
#include <cstdlib>
#include <pthread.h>
using namespace std;
using namespace std::chrono;
const int NUM_THREADS = 7;
const std::string VALUE_TO_WRITE = "TEST";
unsigned long long int total_iterations = 0;
void * RunBenchmark(void * threadid);
class comma_numpunct: public std::numpunct < char > {
protected: virtual char do_thousands_sep() const {
return ',';
}
virtual std::string do_grouping() const {
return "\03";
}
};
void * RunBenchmark(void * threadid) {
unsigned long long int iterations = 0;
std::string benchmark;
int seconds = 0;
std::locale comma_locale(std::locale(), new comma_numpunct());
std::cout.imbue(comma_locale);
auto start = std::chrono::system_clock::now();
auto end = std::chrono::system_clock::now();
do {
start = std::chrono::system_clock::now();
while ((std::chrono::duration_cast < std::chrono::seconds > (end - start).count() != 1)) {
benchmark = VALUE_TO_WRITE;
iterations += 1;
}
total_iterations += iterations;
iterations = 0;
cout << "Total Iterations: " << std::setprecision(0) << std::fixed << total_iterations << "\r";
} while (1);
}
int main(int argc, char ** argv) {
unsigned long long int iterations = 0;
int tc, tn;
pthread_t threads[NUM_THREADS];
for (tn = 0; tn < NUM_THREADS; tn++) {
tc = pthread_create( & threads[tn], NULL, & RunBenchmark, NULL);
}
return 0;
}

How to use mmap for integer input?

I have coded a program that uses mmap as input to fill a integer 2D vector from a .txt file. The code is part of a larger program and will be submitted to a competition. Is there a way to improve the speed using mmap, or by using a different way all together? Here is the code:
#include <fstream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <iostream>
// for mmap:
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
using namespace std;
const char* map_file(const char* fname, size_t& length);
int main()
{
auto start = std::chrono::high_resolution_clock::now();
size_t length;
auto f = map_file("erasmus.in", length);
auto l = f + length;
int i = 0;
bool flag = false;
string lines;
vector<vector<int> > students(10000); //The number of lines is predefined
const char* temp;
while (f && f!=l) {
string element = "";
temp = static_cast<const char*>(memchr(f, '\n', l-f));
for(f = f; f<=temp; f++)
{
if(!isspace(*f))
{
element += *f;
flag = true;
}
if(isspace(*f) && flag == true)
{
flag = false;
int assigned_element = stoi(element);
students[i].push_back(assigned_element);
element = "";
}
}
i++;
temp++;
}
auto finish = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed1 = finish - start;
FILE* output = fopen("erasmus.out", "w");
for (int i = 0; i < students.size(); i++)
{
for (int j = 0; j < students[i].size(); j++)
{
fprintf(output, "%d ", students[i][j]);
}
fprintf(output, "\n");
}
std::cout << "Elapsed time: " << elapsed1.count() << " s\n";
return 0;
}
void handle_error(const char* msg) {
perror(msg);
exit(255);
}
const char* map_file(const char* directory, size_t& length)
{
int fileDirectory = open(directory, O_RDONLY);
if (fileDirectory == -1)
handle_error("open");
// obtain file size
struct stat sb;
if (fstat(fileDirectory, &sb) == -1)
handle_error("fstat");
length = sb.st_size;
const char* map = static_cast<const char*>(mmap(NULL, length, PROT_READ, MAP_PRIVATE, fileDirectory, 0u));
if (map == MAP_FAILED)
handle_error("mmap");
return map;
}
The file will be executed on a linux system, if this helps to find the optimal answer. At the end of each line of the .txt
there is a space character (' ') and a newline('\n')

clockTick function is not declared in this scope

I am putting both the CPP and HPP files here and the error I receive:
I am adding the complete code here and the error I am encountering; kindly help.
Kindly help me in posting this question too.
CPP:
#include "TimeWindowCounter.hpp"
#include <iostream>
#include "../../Common/TimeAnalyser.hpp"
TimeWindowCounter::TimeWindowCounter()
{
init();
}
void TimeWindowCounter::init()
{
boost::atomic<bool> first_order_sent(false);
}
TimeWindowCounter::TimeWindowCounter(double currTime)
{
first_order_sent = true;
startTime = currTime;
endTime = currTime;
orderCount = 0;
ind = 0;
N = 1000;
for (int j =0; j<= 99; j++ )
numberofOrder[j] = 0;
}
TimeWindowCounter::~TimeWindowCounter()
{
}
void TimeWindowCounter::addOrder()
{
orderCount++;
numberofOrder[ind] = orderCount;
}
void TimeWindowCounter::clockTick(const boost::system::error_code& /*e*/, boost::asio::deadline_timer* t, int* count, double* currTime)
{
stopTime = *currTime;
WindowSize = timeAnalyser.getDiffTime_rt(startTime, stopTime);
if (WindowSize.count()*1000 > N)
startTime = startTime + (WindowSize.count()*1000-N);
ind = (ind + 1) % 10;
std::cout << *count << std::endl;
++(*count);
t->expires_at(t->expires_at() + boost::posix_time::milliseconds(1));
t->async_wait(boost::bind(clockTick,boost::asio::placeholders::error, t, count, currTime));
} // 10ms or 100 times a second
int TimeWindowCounter::getNumOfOrders()
{
int sum = 0;
for (int i = 0; i<= 99; i++)
sum = sum + numberofOrder[i];
return sum;
}
void TimeWindowCounter::run(){
io.run();
}
int main()
{
boost::asio::io_service io;
int count = 0;
TimeAnalyser timeAnalyser;
double currTime = timeAnalyser.getClockTime();
TimeWindowCounter * timewindowCounter = new TimeWindowCounter();
boost::asio::deadline_timer t(io, boost::posix_time::milliseconds(10));
t.async_wait(boost::bind(clockTick,boost::asio::placeholders::error, &t, &count, &currTime));
timewindowCounter->run();
for (int j = 0; j <=100000 ; j++)
timewindowCounter->addOrder();
std::cout << "Final count is " << count << std::endl;
}
HPP:
#ifndef TIMEWINDOWCOUNTER
#define TIMEWINDOWCOUNTER
#include <iostream>
#include <boost/chrono.hpp>
#include <boost/atomic.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <cmath>
#include <unistd.h>
#include "../../Common/TimeAnalyser.hpp"
using namespace std;
class TimeWindowCounter
{
TimeAnalyser timeAnalyser;
boost::asio::io_service io;
public:
TimeWindowCounter();
~TimeWindowCounter();
TimeWindowCounter(double currTime);
boost::atomic<bool> first_order_sent;
boost::chrono::duration<double> interval;
double startTime;
double stopTime;
double endTime;
double currTime;
void init();
int numberofOrders;
int orderCount;
int numberofOrder[99];
int ind;
boost::chrono::duration<double> WindowSize;
int N; // WindowSize
void addOrder();
void clockTick(const boost::system::error_code&, boost::asio::deadline_timer* t, int* count, double* currTime); // 10ms or 100 times a second
int getNumOfOrders();
void timer_thread();
void run();
};
#endif
Compile:
g++ -std=c++11 -o TA TimeWindowCounter.cpp -lboost_chrono -lboost_system
Error:
TimeWindowCounter.cpp: In member function ‘void TimeWindowCounter::clockTick(const boost::system::error_code&, boost::asio::deadline_timer*, int*, double*)’:
TimeWindowCounter.cpp:50:93: error: invalid use of non-static member function
t->async_wait(boost::bind(clockTick,boost::asio::placeholders::error, t, count, currTime));
^
TimeWindowCounter.cpp: In function ‘int main()’:
TimeWindowCounter.cpp:80:26: error: ‘clockTick’ was not declared in this scope
t.async_wait(boost::bind(clockTick,boost::asio::placeholders::error, &t, &count, &currTime));
You're binding an instance member function.
You need to qualify the function name and pass a suitable "this" parameter as the first argument:
t->async_wait(boost::bind(&TimeWindowCounter::clockTick, this, boost::asio::placeholders::error, t, count, currTime));
and
t.async_wait(boost::bind(&TimeWindowCounter::clockTick, timewindowCounter, boost::asio::placeholders::error, &t, &count, &currTime));
respectively.
Live Demo
Live On Coliru
#ifndef TIMEWINDOWCOUNTER
#define TIMEWINDOWCOUNTER
#include <iostream>
#include <boost/chrono.hpp>
#include <boost/atomic.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <cmath>
#include <unistd.h>
//#include "../../Common/TimeAnalyser.hpp"
struct TimeAnalyser {
double getClockTime() const { return 0; }
boost::chrono::duration<double> getDiffTime_rt(double, double) const { return boost::chrono::milliseconds(1); }
};
using namespace std;
class TimeWindowCounter {
TimeAnalyser timeAnalyser;
boost::asio::io_service io;
public:
TimeWindowCounter();
~TimeWindowCounter();
TimeWindowCounter(double currTime);
boost::atomic<bool> first_order_sent;
boost::chrono::duration<double> interval;
double startTime;
double stopTime;
double endTime;
double currTime;
void init();
int numberofOrders;
int orderCount;
int numberofOrder[99];
int ind;
boost::chrono::duration<double> WindowSize;
int N; // WindowSize
void addOrder();
void clockTick(const boost::system::error_code&, boost::asio::deadline_timer* t, int* count,
double* currTime); // 10ms or 100 times a second
int getNumOfOrders();
void timer_thread();
void run();
};
#endif
//#include "TimeWindowCounter.hpp"
#include <iostream>
//#include "../../Common/TimeAnalyser.hpp"
TimeWindowCounter::TimeWindowCounter() { init(); }
void TimeWindowCounter::init() { boost::atomic<bool> first_order_sent(false); }
TimeWindowCounter::TimeWindowCounter(double currTime)
{
first_order_sent = true;
startTime = currTime;
endTime = currTime;
orderCount = 0;
ind = 0;
N = 1000;
for (int j = 0; j <= 99; j++)
numberofOrder[j] = 0;
}
TimeWindowCounter::~TimeWindowCounter() {}
void TimeWindowCounter::addOrder()
{
orderCount++;
numberofOrder[ind] = orderCount;
}
void TimeWindowCounter::clockTick(const boost::system::error_code& /*e*/, boost::asio::deadline_timer* t, int* count,
double* currTime)
{
stopTime = *currTime;
WindowSize = timeAnalyser.getDiffTime_rt(startTime, stopTime);
if (WindowSize.count() * 1000 > N)
startTime = startTime + (WindowSize.count() * 1000 - N);
ind = (ind + 1) % 10;
std::cout << *count << std::endl;
++(*count);
t->expires_at(t->expires_at() + boost::posix_time::milliseconds(1));
t->async_wait(boost::bind(&TimeWindowCounter::clockTick, this, boost::asio::placeholders::error, t, count, currTime));
} // 10ms or 100 times a second
int TimeWindowCounter::getNumOfOrders()
{
int sum = 0;
for (int i = 0; i <= 99; i++)
sum = sum + numberofOrder[i];
return sum;
}
void TimeWindowCounter::run() { io.run(); }
int main()
{
boost::asio::io_service io;
int count = 0;
TimeAnalyser timeAnalyser;
double currTime = timeAnalyser.getClockTime();
TimeWindowCounter* timewindowCounter = new TimeWindowCounter();
boost::asio::deadline_timer t(io, boost::posix_time::milliseconds(10));
t.async_wait(boost::bind(&TimeWindowCounter::clockTick, timewindowCounter, boost::asio::placeholders::error, &t, &count, &currTime));
timewindowCounter->run();
for (int j = 0; j <= 100000; j++)
timewindowCounter->addOrder();
std::cout << "Final count is " << count << std::endl;
}
Prints
Final count is 0

undefined reference to function using clock_gettime

I'm trying to create a simple test to time some functions. I'm using the following files main.cpp and testTiming.hpp. I am not able to compile, I get the following error: main.cpp:16: undefined reference to `startProfile(TIME_ID)'. Is there anything incorrect about my function definitions?
testTiming.hpp
#include <iostream>
#include <fstream>
#include <time.h>
#include <stdlib.h>
enum TIME_ID
{
TIME1 = 0,
TIME2 = 1,
NUM_TIMES = 2
};
typedef struct timeTable
{
timespec lastStartTime;
timespec totalTime;
} timeTable;
timeTable mTimeTable[NUM_TIMES];
void inline stopProfile( TIME_ID timeId );
timespec inline diff(timespec start, timespec end)
{
timespec temp;
if ((end.tv_nsec-start.tv_nsec) < 0) {
temp.tv_sec = end.tv_sec - start.tv_sec - 1;
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
} else {
temp.tv_sec = end.tv_sec - start.tv_sec;
temp.tv_nsec = end.tv_nsec - start.tv_nsec;
}
return temp;
}
void inline startprofile( TIME_ID timeId)
{
if (timeId = TIME1)
{
stopProfile(TIME1);
}
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &(mTimeTable[timeId].lastStartTime));
//clock_gettime(CLOCK_REALTIME, &(mTimeTable[timeId].lastStartTime));
};
void inline stopProfile( TIME_ID timeId)
{
timespec stopTime;
timespec diffTime;
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &(stopTime));
//clock_gettime(CLOCK_REALTIME, &(stopTime));
diffTime = diff(mTimeTable[timeId].lastStartTime, stopTime);
mTimeTable[timeId].totalTime.tv_sec += diffTime.tv_sec;
mTimeTable[timeId].totalTime.tv_nsec += diffTime.tv_nsec;
if (timeId != TIME1)
{
startprofile(TIME1);
}
};
void printprofile(void)
{
int i;
for(i = 0; i < NUM_TIMES; i++)
{
switch( i)
{
case TIME1:
printf("PROFILE : TIME1: %f s\n", (float) mTimeTable[i].totalTime.tv_sec + float
(mTimeTable[i].totalTime.tv_nsec / 1000000000.0f) );
break;
case TIME2:
printf("PR0FILE : TIME2P: %d %f s\n", (float) mTimeTable[i].totalTime.tv_sec + float
(mTimeTable[i].totalTime.tv_nsec / 1000000000.0f) );
printf("PR0FILE : TIME2W: %d %f s\n", (float) mTimeTable[i].totalTime.tv_sec + float
(mTimeTable[i].totalTime.tv_nsec) );
break;
default:
break;
}
}
};
main.cpp
#include "testTiming.hpp"
#include <time.h>
using namespace std;
void inline startProfile( TIME_ID timeId );
void inline printProfile( void );
int main(int argc, char** argv)
{
int sec = 5;
startProfile(TIME1);
sleep(sec);
stopProfile(TIME1);
//printProfile();
return 0;
}
Makefile
ls SHELL = /bin/csh
all :
g++ main.cpp -g -o timeTest
clean:
rm -f timeTest

DateTime Validation as 25-Jul-2012 15:08:23

I am using below method to validate Date.
How to format month in string ?
bool CDateTime :: IsValidDate(char* pcDate) //pcDate = 25-Jul-2012 15:08:23
{
bool bVal = true;
int iRet = 0;
struct tm tmNewTime;
iRet = sscanf_s(pcDate, "%d-%d-%d %d:%d:%d", &tmNewTime.tm_mon, &tmNewTime.tm_mday, &tmNewTime.tm_year, &tmNewTime.tm_hour, &tmNewTime.tm_min, &tmNewTime.tm_sec);
if (iRet == -1)
bVal = false;
if (bVal == true)
{
tmNewTime.tm_year -= 1900;
tmNewTime.tm_mon -= 1;
bVal = IsValidTm(&tmNewTime);
}
return bVal;
}
Using strptime:
#include <time.h>
char *str = "25-Jul-2012 15:08:23";
struct tm tm;
if (strptime (str, "%d-%b-%Y %H:%M:%S", &tm) == NULL) {
/* Bad format !! */
}
The C++11 way of doing this is:
#include <iostream>
#include <iomanip>
#include <ctime>
#include <chrono>
int main()
{
auto now = std::chrono::system_clock::now();
auto now_c = std::chrono::system_clock::to_time_t(now);
std::cout << "Now is " << std::put_time(std::localtime(&now_c), "%d-%b-%Y %H:%M:%S") << '\n';
}
Note: The stream I/O manipulator std::put_time is not implemented fully in all compilers yet. GCC 4.7.1 does not have it for example.