Changes to readme, add increase runners, fix in time rotor

dev-own-engine
marcelb 7 months ago
parent 8fdf56d1bb
commit b123e9305d
  1. 56
      README.md
  2. 5
      lib/rotor.hpp
  3. 51
      lib/runner.hpp
  4. 119
      test/test.cpp

@ -8,12 +8,12 @@ A C++ library for event-driven asynchronous multi-threaded programming.
- Object oriented - Object oriented
- Small and easy to integrate - Small and easy to integrate
- Header only - Header only
- Asynchronous launch functions - Asynchronous programming
- Multithread parallel execution of tasks - Multithread
- Timer functions: interval, timeout - Asynchronous timer functions: interval, timeout
- Events (on, emit) - Typed events (on, emit)
- Event loop - Event loops
- Parallel execution loops
## Installation ## Installation
Just download the latest release and unzip it into your project. Just download the latest release and unzip it into your project.
@ -37,7 +37,7 @@ Time asynchronous functions
```c++ ```c++
// start interval // start interval
interval inter1 ([&]() { interval inter1 ([]() {
cout << "Interval 1" << endl; cout << "Interval 1" << endl;
}, 1000); }, 1000);
@ -45,7 +45,7 @@ interval inter1 ([&]() {
inter1.clear(); inter1.clear();
// start timeout // start timeout
timeout time1 ( [&] () { timeout time1 ( [] () {
cout << "Timeout 1 " << endl; cout << "Timeout 1 " << endl;
}, 10000); }, 10000);
@ -60,8 +60,8 @@ Make functions asynchronous
*/ */
auto res1 = on_async.put_task( [] () { auto res1 = on_async.put_task( [] () {
cout << "Jebiga " <<endl; cout << "Not except " <<endl;
throw string ("jebiga!!"); throw string ("Is except!");
}); });
try { try {
@ -71,22 +71,50 @@ try {
} }
/** /**
* Run an function asyncronic * Run an lambda function asyncronic
*/ */
asynco( []() { asynco( []() {
sleep_for(2s); // only for simulate log duration function sleep_for(2s); // only for simulating long duration function
cout << "asynco" << endl; cout << "asynco" << endl;
return 5; return 5;
}); });
/**
* Run not lambda function
*/
void notLambdaFunction() {
cout << "Call to not lambda function" << endl;
}
asynco (notLambdaFunction);
/**
* Run class method
*/
class clm {
public:
void classMethode() {
cout << "Call class method" << endl;
}
};
clm classes;
asynco( [&classes] () {
classes.classMethode();
});
/** /**
* Wait after runned as async * Wait after runned as async
*/ */
auto a = asynco( []() { auto a = asynco( []() {
sleep_for(2s); // only for simulate log duration function sleep_for(2s); // only for simulating long duration function
cout << "asynco" << endl; cout << "asynco" << endl;
return 5; return 5;
}); });
@ -98,7 +126,7 @@ cout << wait(move(a)) << endl;
*/ */
cout << wait(asynco( [] () { cout << wait(asynco( [] () {
sleep_for(chrono::seconds(1)); // only for simulate log duration function sleep_for(chrono::seconds(1)); // only for simulating long duration function
cout << "wait end" << endl; cout << "wait end" << endl;
return 4; return 4;
})) << endl; })) << endl;

@ -89,12 +89,17 @@ class rotor {
void remove(const int& position) { void remove(const int& position) {
lock_guard<mutex> lock(te_m); lock_guard<mutex> lock(te_m);
tevents.erase(tevents.begin()+position); tevents.erase(tevents.begin()+position);
update_sampling();
} }
/** /**
* Updates the idle time of the loop, according to twice the frequency of available events * Updates the idle time of the loop, according to twice the frequency of available events
*/ */
void update_sampling() { void update_sampling() {
if (tevents.empty()) {
sampling = 100;
return;
}
sampling = tevents[0]->time; sampling = tevents[0]->time;
for (int i=0; i<tevents.size(); i++) { for (int i=0; i<tevents.size(); i++) {
if (sampling > tevents[i]->time) { if (sampling > tevents[i]->time) {

@ -28,22 +28,19 @@ class runner {
condition_variable cv; condition_variable cv;
bool stop; bool stop;
public:
/** /**
* The constructor starts as many threads as the system has cores, * Increase number of runners
* and runs an event loop inside each one.
* Each event loop waits for tasks from the stack and executes them.
*/ */
runner(size_t pool_size = thread::hardware_concurrency()) : stop(false) { void increase_runners(unsigned int increase) {
for (size_t i = 0; i < pool_size; ++i) { for (size_t i = 0; i < increase; ++i) {
runners.emplace_back( thread([this] { runners.emplace_back( thread([&] {
while (true) { while (!stop) {
function<void()> task; function<void()> task;
{ {
unique_lock<mutex> lock(q_io); unique_lock<mutex> lock(q_io);
cv.wait(lock, [this] { return stop || !tasks.empty(); }); cv.wait(lock, [this] { return stop || !tasks.empty(); });
if (stop && tasks.empty()) // if (stop && tasks.empty())
if (stop)
return; return;
task = move(tasks.front()); task = move(tasks.front());
tasks.pop(); tasks.pop();
@ -54,6 +51,23 @@ class runner {
} }
} }
public:
/**
* The constructor starts as many threads as the system has cores,
* and runs an event loop inside each one.
* Each event loop waits for tasks from the stack and executes them.
*/
runner(size_t pool_size = thread::hardware_concurrency()) : stop(false) {
if (pool_size < 4) {
pool_size = 4;
}
increase_runners(pool_size);
// start_all_runners(pool_size);
}
/** /**
* With the method, we send the callback function and its arguments to the task stack * With the method, we send the callback function and its arguments to the task stack
*/ */
@ -78,6 +92,22 @@ class runner {
return res; return res;
} }
/**
* Change the number of runners
*/
void change_runners (unsigned int num_of_runners) {
if (num_of_runners == 0 || num_of_runners > 64) {
throw runtime_error("Not allowed runners size");
}
int difference = num_of_runners - count_threads();
if (difference < 0) { // reduce
throw runtime_error("Is not allowed to reduce runners");
} else if (difference > 0) { // increase
increase_runners(difference);
}
}
/** /**
* Returns the number of tasks the runner has to perform * Returns the number of tasks the runner has to perform
*/ */
@ -104,6 +134,7 @@ class runner {
for (thread& runner : runners) { for (thread& runner : runners) {
runner.join(); runner.join();
} }
runners.clear();
} }
}; };

@ -41,6 +41,17 @@ void promise_reject (int _time) {
return _promise.get_future().get(); return _promise.get_future().get();
} }
void notLambdaFunction() {
cout << "Call to not lambda function" << endl;
}
class clm {
public:
void classMethode() {
cout << "Call class method" << endl;
}
};
// ------------------ EXTEND OWN CLASS WITH EVENTS ------------------- // ------------------ EXTEND OWN CLASS WITH EVENTS -------------------
class myOwnClass : public event<int> { class myOwnClass : public event<int> {
@ -50,6 +61,7 @@ class myOwnClass : public event<int> {
int main () { int main () {
on_async.change_runners(64);
auto start = rtime_ms(); auto start = rtime_ms();
@ -59,6 +71,26 @@ int main () {
* Init interval and timeout; clear interval and timeout * Init interval and timeout; clear interval and timeout
*/ */
// ovo ne radi
// vector<interval> interv;
// vector<timeout> tmout;
// for (int i=0; i< 20; i++) {
// interv.push_back( interval( [i] () {
// cout << "interval " << i << endl;
// }, 1000));
// tmout.push_back( timeout( [i] () {
// cout << "timeout " << i << endl;
// }, 1000*i));
// }
// ovo valja popravit
// interval( [] () {
// cout << "interval " << endl;
// }, 1000);
// interval inter1 ([&]() { // interval inter1 ([&]() {
// cout << "interval prvi " << rtime_ms() - start << endl; // cout << "interval prvi " << rtime_ms() - start << endl;
// }, 1000); // }, 1000);
@ -83,11 +115,11 @@ int main () {
// time1.clear(); // time1.clear();
// }, 2000); // }, 2000);
// ------------------------ MAKE FUNCTIONS ASYNCHRONOUS ------------------------- // // ------------------------ MAKE FUNCTIONS ASYNCHRONOUS -------------------------
/** // /**
* Put task directly and get returned value - it is not recommended to use it // * Put task directly and get returned value - it is not recommended to use it
*/ // */
// auto res1 = on_async.put_task( [] () { // auto res1 = on_async.put_task( [] () {
// cout << "Jebiga " <<endl; // cout << "Jebiga " <<endl;
@ -100,9 +132,9 @@ int main () {
// cout << except << endl; // cout << except << endl;
// } // }
/** // /**
* Run an function asyncronic // * Run an function asyncronic
*/ // */
// asynco( []() { // asynco( []() {
// sleep_for(2s); // only for simulate log duration function // sleep_for(2s); // only for simulate log duration function
@ -110,10 +142,29 @@ int main () {
// return 5; // return 5;
// }); // });
// /**
// * Call not lambda function
// */
/** // asynco (notLambdaFunction);
* Wait after runned as async
*/ // /**
// * Call class method
// */
// clm classes;
// asynco( [&classes] () {
// classes.classMethode();
// });
// // sleep(5);
// /**
// * Wait after runned as async
// */
// auto a = asynco( []() { // auto a = asynco( []() {
// sleep_for(2s); // only for simulate log duration function // sleep_for(2s); // only for simulate log duration function
@ -123,9 +174,9 @@ int main () {
// cout << wait(move(a)) << endl; // cout << wait(move(a)) << endl;
/** // /**
* Wait async function call and use i cout // * Wait async function call and use i cout
*/ // */
// cout << wait(asynco( [] () { // cout << wait(asynco( [] () {
// sleep_for(chrono::seconds(1)); // only for simulate log duration function // sleep_for(chrono::seconds(1)); // only for simulate log duration function
@ -133,16 +184,16 @@ int main () {
// return 4; // return 4;
// })) << endl; // })) << endl;
/** // /**
* Sleep with timeout sleep implement // * Sleep with timeout sleep implement
*/ // */
// sleep_to(3000); // sleep_to(3000);
// cout << "sleep_to " << rtime_ms() - start << endl; // cout << "sleep_to " << rtime_ms() - start << endl;
/** // /**
* Catch promise reject // * Catch promise reject
*/ // */
// try { // try {
// promise_reject(3000); // promise_reject(3000);
@ -153,9 +204,9 @@ int main () {
// cout << "promise_reject " << rtime_ms() - start << endl; // cout << "promise_reject " << rtime_ms() - start << endl;
/** // /**
* Nested asynchronous invocation // * Nested asynchronous invocation
*/ // */
// asynco( [] { // asynco( [] {
@ -165,11 +216,11 @@ int main () {
// }); // });
// }); // });
// --------------- EVENTS ------------------- // // --------------- EVENTS -------------------
/** // /**
* initialization of typed events // * initialization of typed events
*/ // */
// event<int, int> ev2int; // event<int, int> ev2int;
// event<int, string> evintString; // event<int, string> evintString;
@ -187,11 +238,11 @@ int main () {
// cout << "Void emited" << endl; // cout << "Void emited" << endl;
// }); // });
// sleep(1); // // sleep(1);
/** // /**
* Emit // * Emit
*/ // */
// ev2int.emit("sum", 5, 8); // ev2int.emit("sum", 5, 8);
@ -201,9 +252,9 @@ int main () {
// sleep(1); // sleep(1);
// evoid.emit("void"); // evoid.emit("void");
/** // /**
* Own class // * Own class
*/ // */
// myOwnClass myclass; // myOwnClass myclass;
@ -215,7 +266,7 @@ int main () {
// cout << "Constructed " << i << endl; // cout << "Constructed " << i << endl;
// }); // });
sleep(10000); // only for testing sleep(100000); // only for testing
return 0; return 0;
} }

Loading…
Cancel
Save