commit
03b11840f4
@ -0,0 +1,16 @@ |
|||||||
|
{ |
||||||
|
"configurations": [ |
||||||
|
{ |
||||||
|
"name": "Linux", |
||||||
|
"includePath": [ |
||||||
|
"${workspaceFolder}/**" |
||||||
|
], |
||||||
|
"defines": [], |
||||||
|
"compilerPath": "/usr/bin/gcc", |
||||||
|
"cStandard": "c17", |
||||||
|
"cppStandard": "gnu++17", |
||||||
|
"intelliSenseMode": "linux-gcc-x64" |
||||||
|
} |
||||||
|
], |
||||||
|
"version": 4 |
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
{ |
||||||
|
"files.associations": { |
||||||
|
"iostream": "cpp", |
||||||
|
"functional": "cpp", |
||||||
|
"thread": "cpp", |
||||||
|
"chrono": "cpp", |
||||||
|
"ostream": "cpp", |
||||||
|
"condition_variable": "cpp", |
||||||
|
"array": "cpp", |
||||||
|
"atomic": "cpp", |
||||||
|
"cwchar": "cpp", |
||||||
|
"deque": "cpp", |
||||||
|
"unordered_map": "cpp", |
||||||
|
"vector": "cpp", |
||||||
|
"exception": "cpp", |
||||||
|
"initializer_list": "cpp", |
||||||
|
"iosfwd": "cpp", |
||||||
|
"mutex": "cpp", |
||||||
|
"new": "cpp", |
||||||
|
"ratio": "cpp", |
||||||
|
"stdexcept": "cpp", |
||||||
|
"tuple": "cpp", |
||||||
|
"type_traits": "cpp", |
||||||
|
"utility": "cpp", |
||||||
|
"future": "cpp" |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
{ |
||||||
|
"tasks": [ |
||||||
|
{ |
||||||
|
"type": "cppbuild", |
||||||
|
"label": "C/C++: gcc build active file", |
||||||
|
"command": "/usr/bin/g++", |
||||||
|
"args": [ |
||||||
|
"-fdiagnostics-color=always", |
||||||
|
"-g", |
||||||
|
"${file}", |
||||||
|
"-o", |
||||||
|
"${fileDirname}/${fileBasenameNoExtension}" |
||||||
|
], |
||||||
|
"options": { |
||||||
|
"cwd": "${fileDirname}" |
||||||
|
}, |
||||||
|
"problemMatcher": [ |
||||||
|
"$gcc" |
||||||
|
], |
||||||
|
"group": { |
||||||
|
"kind": "build", |
||||||
|
"isDefault": true |
||||||
|
}, |
||||||
|
"detail": "Task generated by Debugger." |
||||||
|
} |
||||||
|
], |
||||||
|
"version": "2.0.0" |
||||||
|
} |
@ -0,0 +1,93 @@ |
|||||||
|
#ifndef _ASYNCO_ |
||||||
|
#define _ASYNCO_ |
||||||
|
|
||||||
|
#include "loop.hpp" |
||||||
|
|
||||||
|
using namespace std; |
||||||
|
|
||||||
|
namespace marcelb { |
||||||
|
|
||||||
|
#ifndef ON_ASYNC |
||||||
|
#define ON_ASYNC |
||||||
|
AsyncLoop on_async; |
||||||
|
#endif |
||||||
|
|
||||||
|
class interval { |
||||||
|
bool run = true; |
||||||
|
function<void()> callback; |
||||||
|
const time_t _duration; |
||||||
|
|
||||||
|
public: |
||||||
|
interval(function<void()> func, const time_t duration): callback(func), _duration(duration) { |
||||||
|
#ifndef ON_ASYNC |
||||||
|
throw string("Not on_async defined!"); |
||||||
|
#endif |
||||||
|
|
||||||
|
auto task = [&] () { |
||||||
|
while (run) { |
||||||
|
this_thread::sleep_for(chrono::milliseconds(_duration)); |
||||||
|
if (run) { |
||||||
|
callback(); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
on_async.put_task(task); |
||||||
|
} |
||||||
|
|
||||||
|
void clear() { |
||||||
|
run = false; |
||||||
|
} |
||||||
|
|
||||||
|
~interval() { |
||||||
|
clear(); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
class timeout { |
||||||
|
bool run = true; |
||||||
|
function<void()> callback; |
||||||
|
const time_t _duration; |
||||||
|
|
||||||
|
public: |
||||||
|
timeout(function<void()> f, const time_t duration): callback(f), _duration(duration) { |
||||||
|
#ifndef ON_ASYNC |
||||||
|
throw string("Not on_async defined!"); |
||||||
|
#endif |
||||||
|
|
||||||
|
auto task = [&] () { |
||||||
|
this_thread::sleep_for(chrono::milliseconds(_duration)); |
||||||
|
if (run) { |
||||||
|
callback(); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
on_async.put_task(task); |
||||||
|
} |
||||||
|
|
||||||
|
void clear() { |
||||||
|
run = false; |
||||||
|
} |
||||||
|
|
||||||
|
~timeout() { |
||||||
|
clear(); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
template<class F, class... Args> |
||||||
|
auto asynco(F&& f, Args&&... args) -> future<typename result_of<F(Args...)>::type> { |
||||||
|
using return_type = typename result_of<F(Args...)>::type; |
||||||
|
|
||||||
|
future<return_type> res = on_async.put_task(bind(forward<F>(f), forward<Args>(args)...)); |
||||||
|
return res; |
||||||
|
} |
||||||
|
|
||||||
|
template<typename T> |
||||||
|
T wait(future<T> r) { |
||||||
|
return r.get(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,40 @@ |
|||||||
|
#ifndef _EVENT_ |
||||||
|
#define _EVENT_ |
||||||
|
|
||||||
|
#include <iostream> |
||||||
|
#include <map> |
||||||
|
#include <string> |
||||||
|
#include <functional> |
||||||
|
|
||||||
|
using namespace std; |
||||||
|
|
||||||
|
namespace marcelb { |
||||||
|
|
||||||
|
class event { |
||||||
|
map<string, function<void(const tuple<>&)>> events; |
||||||
|
public: |
||||||
|
|
||||||
|
template <typename... Args> |
||||||
|
void on(const string& key, function<void(Args...)> f) { |
||||||
|
// events[key] = [f](Args... args) {
|
||||||
|
// f(args...);
|
||||||
|
// };
|
||||||
|
} |
||||||
|
|
||||||
|
template <typename... Args> |
||||||
|
void emit(const string& key, Args&&... args) { |
||||||
|
if (events.find(key) == events.end()) { |
||||||
|
cout << "No defined listener for event: " << key << endl; |
||||||
|
return; |
||||||
|
} |
||||||
|
else { |
||||||
|
for (auto& func : events[key]) { |
||||||
|
func(forward<Args>(args)...); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,91 @@ |
|||||||
|
#ifndef _LOOP_ |
||||||
|
#define _LOOP_ |
||||||
|
|
||||||
|
#include <thread> |
||||||
|
#include <vector> |
||||||
|
#include <queue> |
||||||
|
#include <functional> |
||||||
|
#include <mutex> |
||||||
|
#include <condition_variable> |
||||||
|
#include <future> |
||||||
|
|
||||||
|
using namespace std; |
||||||
|
|
||||||
|
namespace marcelb { |
||||||
|
|
||||||
|
#ifdef ON_ASYNC |
||||||
|
extern AsyncLoop on_async; |
||||||
|
#endif |
||||||
|
|
||||||
|
class AsyncLoop { |
||||||
|
private: |
||||||
|
vector<thread> workers; |
||||||
|
queue<function<void()>> tasks; |
||||||
|
mutex q_io; |
||||||
|
condition_variable cv; |
||||||
|
bool stop; |
||||||
|
|
||||||
|
public: |
||||||
|
AsyncLoop(size_t pool_size = thread::hardware_concurrency()) : stop(false) { |
||||||
|
for (size_t i = 0; i < pool_size; ++i) { |
||||||
|
workers.emplace_back([this] { |
||||||
|
while (true) { |
||||||
|
function<void()> task; |
||||||
|
{ |
||||||
|
unique_lock<mutex> lock(q_io); |
||||||
|
cv.wait(lock, [this] { return stop || !tasks.empty(); }); |
||||||
|
if (stop && tasks.empty()) |
||||||
|
return; |
||||||
|
task = move(tasks.front()); |
||||||
|
tasks.pop(); |
||||||
|
} |
||||||
|
task(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
template<class F, class... Args> |
||||||
|
auto put_task(F&& f, Args&&... args) |
||||||
|
-> future<typename result_of<F(Args...)>::type> { |
||||||
|
using return_type = typename result_of<F(Args...)>::type; |
||||||
|
|
||||||
|
auto task = make_shared<packaged_task<return_type()>>(bind(forward<F>(f), forward<Args>(args)...)); |
||||||
|
future<return_type> res = task->get_future(); |
||||||
|
{ |
||||||
|
unique_lock<mutex> lock(q_io); |
||||||
|
|
||||||
|
if (stop) { |
||||||
|
throw runtime_error("Pool is stoped!"); |
||||||
|
} |
||||||
|
|
||||||
|
tasks.emplace([task]() { (*task)(); }); |
||||||
|
} |
||||||
|
|
||||||
|
cv.notify_one(); |
||||||
|
return res; |
||||||
|
} |
||||||
|
|
||||||
|
unsigned int count_tasks() { |
||||||
|
return tasks.size(); |
||||||
|
} |
||||||
|
|
||||||
|
unsigned int count_threads() { |
||||||
|
return workers.size(); |
||||||
|
} |
||||||
|
|
||||||
|
~AsyncLoop() { |
||||||
|
{ |
||||||
|
unique_lock<mutex> lock(q_io); |
||||||
|
stop = true; |
||||||
|
} |
||||||
|
cv.notify_all(); |
||||||
|
for (thread& worker : workers) |
||||||
|
worker.join(); |
||||||
|
} |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,104 @@ |
|||||||
|
|
||||||
|
#include "../lib/loop.hpp" |
||||||
|
#include "../lib/asynco.hpp" |
||||||
|
// #include "../lib/event.hpp"
|
||||||
|
#include <iostream> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
using namespace std; |
||||||
|
using namespace marcelb; |
||||||
|
using namespace this_thread; |
||||||
|
|
||||||
|
#ifndef ON_ASYNC |
||||||
|
#define ON_ASYNC |
||||||
|
AsyncLoop on_async; |
||||||
|
#endif |
||||||
|
|
||||||
|
int main () { |
||||||
|
|
||||||
|
auto start = chrono::high_resolution_clock::now(); |
||||||
|
|
||||||
|
interval inter1 ([&]() { |
||||||
|
cout << "interval prvi " << chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start).count() << endl; |
||||||
|
}, 1000); |
||||||
|
|
||||||
|
cout << "Blokira stoka" << endl; |
||||||
|
|
||||||
|
interval inter2 ([&]() { |
||||||
|
cout << "interval drugi " << chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start).count() << endl; |
||||||
|
}, 2000); |
||||||
|
|
||||||
|
interval inter3 ([&]() { |
||||||
|
cout << "interval treći " << chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start).count() << endl; |
||||||
|
}, 3000); |
||||||
|
|
||||||
|
timeout time1 ( [&] () { |
||||||
|
cout << "Close interval 1 i 2 " << chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start).count() << endl; |
||||||
|
inter1.clear(); |
||||||
|
inter2.clear(); |
||||||
|
}, 10000); |
||||||
|
|
||||||
|
timeout time2 ([&] () { |
||||||
|
cout << "Close interval 3 " << chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start).count() << endl; |
||||||
|
inter3.clear(); |
||||||
|
}, 20000); |
||||||
|
|
||||||
|
|
||||||
|
// for (int i = 0; i < 8; ++i) {
|
||||||
|
// pool.put_task( [&] (int id) {
|
||||||
|
// this_thread::sleep_for(chrono::seconds(1));
|
||||||
|
// cout << a*i << endl;
|
||||||
|
// }, i);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// auto res1 = pool.put_task( [] () {
|
||||||
|
// cout << "Jebiga " <<endl;
|
||||||
|
// throw string ("jebiga!!");
|
||||||
|
// });
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// res1.get();
|
||||||
|
// } catch (const string except) {
|
||||||
|
// cout << except << endl;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// auto res = pool.put_task( []() {
|
||||||
|
// this_thread::sleep_for(chrono::seconds(1));
|
||||||
|
// return 4;
|
||||||
|
// });
|
||||||
|
|
||||||
|
// cout << wait(asynco( [] () {
|
||||||
|
// sleep_for(chrono::seconds(1));
|
||||||
|
// cout << "RETURN" << endl;
|
||||||
|
// return 4;
|
||||||
|
// })) << endl;
|
||||||
|
|
||||||
|
// asynco( []() {
|
||||||
|
// sleep_for(2s);
|
||||||
|
// cout << "RETURN 2" << endl;
|
||||||
|
// return 5;
|
||||||
|
// });
|
||||||
|
|
||||||
|
// cout << wait(pool.put_task( []() {
|
||||||
|
// this_thread::sleep_for(chrono::seconds(1));
|
||||||
|
// return 7;
|
||||||
|
// }));
|
||||||
|
|
||||||
|
|
||||||
|
// cout << wait(run1) << endl;
|
||||||
|
|
||||||
|
// event dog;
|
||||||
|
|
||||||
|
// dog.on("roge", [](int a, int b) {
|
||||||
|
// cout << "Rogeee" << a << b << endl;
|
||||||
|
// });
|
||||||
|
|
||||||
|
// sleep(5);
|
||||||
|
|
||||||
|
// dog.emit("roge", 5, 8);
|
||||||
|
|
||||||
|
sleep(1000); |
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
Loading…
Reference in new issue