170 похожих чатов

#Include <iostream> using namespace std; #include <chrono> #include <thread> #include <mutex> #include <queue> #include <condition_variable> using namespace

std::chrono;
using namespace std;

template<typename F>
struct Job {
time_point<system_clock> time_to_exec;
F func;
};

template<typename F>
inline bool operator<(const Job<F> &lhs, const Job<F> &rhs) {
return lhs.time_to_exec < rhs.time_to_exec;
};

struct Executor
{
Executor() {
runner = thread(&Executor::running, this);
}

~Executor() {
unique_lock<mutex> lock(queue_mutex);
stop = true;
runner.join();
}

void running() {
while(not stop) {
unique_lock<mutex> lock(queue_mutex);

if(jobs.empty()) {
cv.wait(lock, [this] () {not jobs.empty() || stop;});
} else if (jobs.top().time_to_exec > system_clock::now()) {
cv.wait_until(lock, jobs.top().time_to_exec, [this]() {not jobs.empty() || stop;});
} else {
auto job = jobs.top();
jobs.pop();
lock.unlock();

job();
}
}
}

template<typename F>
void exec(F f, milliseconds timeout) {
Job job(f, system_clock::now() + timeout);

unique_lock<mutex> lock(queue_mutex);
jobs.push(job);
cv.notify_one();
}

priority_queue<Job<F>> jobs; // <-----------?... o_O
mutex queue_mutex;
condition_variable cv;
thread runner;
bool stop = false;
};

string str = "1234567";
int foo(int 5) {
cout << "out finally!" << str[5] << endl;
};

int main()
{
Executor executor;
executor.exec([](){cout << "out finally!";}, seconds{5});
executor.exec(&foo, 5, seconds{7});
cout<<"Hello World";

return 0;
}

21 ответов

42 просмотра

А что не работает? Виснет в деструкторе Executor?

Я удалил твой пост с длинной ссылкой, сори. Если надо - пришли как-то по-другому

Vladimir- Автор вопроса
Alexander Pshenichnikov
А что не работает? Виснет в деструкторе Executor?

Не компилится. Получается, Job при создание параметризуется конкретным задаваемым типом функции. А в очереди нужно знать тип Job, который должен быть один - параметризирован лишь одним типом параметра == одним типом функции, что сильно ограничивает применение.

Vladimir
Не компилится. Получается, Job при создание параме...

Гляньте тут, сравните со своим кодом https://godbolt.org/z/xdKoqExzo

Vladimir- Автор вопроса
Alexander Pshenichnikov
Гляньте тут, сравните со своим кодом https://godb...

Вау) Здорово) Спасибо) Т.е. Executor<std::function<void()>> executor; std::function<void()> - как общий тип F, под который подходит любая сигнатура функции? Что обычной, что передаваемой с параметрами, обёрнутая в bind?

Vladimir
Не компилится. Получается, Job при создание параме...

А как ты собираешься эти разные функции вызывать потом ? Надо сводить это всё к одному виду функций

Vladimir
Вау) Здорово) Спасибо) Т.е. Executor<std::function...

Да, std::function<void()> - "универсальный" тип для жобы без аргументов и возвращающей void.

Vladimir- Автор вопроса
Alexander Pshenichnikov
Да, std::function<void()> - "универсальный" тип дл...

И что к такой функции можно свести любые типы функции. Ну, почти любые, получается. Любые с точки зрения - хоть какие передаваемые параметры. Без возвращаемого значения просто.

Vladimir- Автор вопроса

Ну вот в этом и загвоздка была. Что я не знал о таком универсальном типе.

Vladimir- Автор вопроса

И что к такой функции можно свести любые типы функции. Ну, почти любые, получается. Любые с точки зрения - хоть какие передаваемые параметры. Без возвращаемого значения просто.

Vladimir
Ну вот в этом и загвоздка была. Что я не знал о та...

Не совсем понял в отношении универсальный. Это же конкретная сигнатура, ничего не принимает, ничего не отдает.

Vladimir
И что к такой функции можно свести любые типы функ...

А ты имеешь ввиду универсальный в том плане, что в нее можно передать не только голую функцию, а например, класс, с оператором "функция" (часто именуемый функтор), это да. Но сигнатура должна четко совпадать.

Vladimir- Автор вопроса
The Pressbraker
А ты имеешь ввиду универсальный в том плане, что в...

Ну да. Спасибо Александру. Сейчас классно получилось, что можно передать: void foo(); и void bar(int x, char y) и лямбду похожей сигнатуры Если нужно возвращаемое значение - это уже, наверное, по-другому реализовывать. Видел что-то похожее с выдачей пользователю future. Т.е. асинхронно/параллельно исполнили и положили результат. Сверху/в другом ожидающем потоке просто future.get() - забираешь результат.

Vladimir
Ну да. Спасибо Александру. Сейчас классно получило...

Я не знал, что в std::function<void()> можно положить void bar(int x, char y). Буду знать. Спасибо.

Alexander Pshenichnikov
Да, std::function<void()> - "универсальный" тип дл...

А где про это почитать? На cppref не вижу, вроде

Андрей Таусинов
А где про это почитать? На cppref не вижу, вроде

Так статья про std::function. ... is a general-purpose polymorphic function wrapper... https://en.cppreference.com/w/cpp/utility/functional/function

Alexander Pshenichnikov
Так статья про std::function. ... is a general-pur...

не, именно про то, что в std::function<void()> можно класть любые функции

Ну, не любые вообще. Без аргументов и без возвращаемого значения. В той же статье написно

Alexander Pshenichnikov
Ну, не любые вообще. Без аргументов и без возвраща...

А, все-таки без аргументов, тогда все нормально. Просто в https://t.me/supapro/1353545 меня смутило "Я не знал, что в std::function<void()> можно положить void bar(int x, char y)"

Похожие вопросы

Обсуждают сегодня

Комрады, хотел уточнить. Проперть в OnDestroy юнита-хозяина по-прежнему доступна? И еще уточнение: finalization юнита наступает раньше или позже OnDestroy?
Ed Doc
40
А как старый хаскел с новым стыковать ? потому как тут работает https://play.haskell.org/saved/C3xpMzcd, а вот тут https://stepik.org/lesson/7602/step/9?unit=1473 нет ошибка C...
Fedor
44
Вопрос, вот задание https://stepik.org/lesson/7602/step/9?unit=1473 вот код и ошибка, удивляет, что требуется еще и Semigroup так и должно быть, или я опять делаю ошибки ? htt...
Fedor
14
Вообще, меня бы даже такой вариант, наверное устроил бы: try tag.Read(0); finally end; Но этот AV не ловится и программа завершается Exception EAccessViolation in module C...
notme
12
Проблема с Windows scripting control Множество объектов получают iDispatch обертки и отдаются в скрипты. При этом скрипты могут эти обертки держать живыми очень долго, наприм...
Arioch The
16
Скажите, можно ли как-то "переместить" динамический массив из одной переменной в другую? Скажем, переместить из TList<> в TArray<>. Именно переместить, а не скопировать. Если ...
Eugene Krasnikov (ᴊɪɴ x)
37
Да и вообще... как VBS/VBA производит вызов методов тогда? Как мне на Delphi сделать точно также, блин.... VBS/VBA не падают, а возвращают нормальный СОМ-объект, где можно про...
notme
10
Всем доброго времени суток! В BDE в своё время был файл BDEINST.dll который, как я понимаю, содержал всё что нужно для инсталляции BDE. Если посмотреть на дату его создания то...
Mikhail Tchervonenko
2
Я тут пытаюсь переработать архитектуру подсистемы памяти ядра во что-то осмысленное. Есть pmm, который создает набор range’ей(пока что только для ядра, потом для юзерспейса), ...
Evg Resh
9
комрады, че-та лыжы не едут var tmpFont: TFont; begin tmpFont:= TFont.Create; try case rgFontColor.ItemIndex of 0: tmpFont.Color:= clWindowText; 1: tmpFo...
Ed Doc
34
Карта сайта