cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
89 stars 0 forks source link

Установка приоритетов потокам #457

Open maksimus1210 opened 3 years ago

maksimus1210 commented 3 years ago

В STL и Boost есть классы для работы с потоками, но устанавливать приоритеты потокам приходится через сторонние библиотеки как pthread. Для каждой ОС этот код разный, хотелось бы иметь стандартные средства для управления приоритетом потока.

std::thread thread([](){ std::cout << "Hello world!" }, std::thread::priority::high_priority);

GeorgyFirsov commented 3 years ago

Тогда уж и для std::jthread надо такое вводить.

А еще подумать, как быть с std::async, так как там задача по стандарту может выполняться в отдельном потоке. Напрашивается вопрос, а почему же и тут тогда приоритет нельзя задать. Интересный момент возникает, если задача не выполняется в отдельном потоке. Тогда меняется приоритет текущего потока или как?

maksimus1210 commented 3 years ago

Не думаю, что для std::async нужно устанавливать приоритеты. Вместо std::async лучше использовать std::future/promise. При написании realtime программ нужно некоторым потокам задавать высокий приоритет, так как обработка данных в приоритете над GUI, сейчас нужно для каждой ОС писать собственную реализацию, что очень не удобно.

DymOK93 commented 2 years ago

Любопытная идея. Пока хотелось бы обсудить следующие проблемы:

Насчёт std::async тоже нужно подумать: хоть она и непопулярна, запуск задачи с background-приоритетом - например, скачивания файла - может быть удобным.

maksimus1210 commented 2 years ago

Я не сталкивался с задачей изменения приоритета потока во время его выполнения, обычно заранее известен приоритет задачи. На мой взгляд логично передавать приоритет потока при передаче функтора. Тогда всё выглядело бы просто и понятно.

std::thread thread([](){ ... }, std::thread::priority::high_priority);

и для std::async

auto ret = std::async(std::launch::async, std::thread::priority::high_priority, [](){ ... });

DymOK93 commented 2 years ago

Тогда возвращаемся к вопросу сигнализации о неудаче :) Изменять приоритет потока в ходе работы тоже иногда приходится: например, поток закончил ожидать IO, передает задачу в соседний worker-thread (предположим, что задача небольшая, и пул не требуется), попутно повышая его приоритет

maksimus1210 commented 2 years ago

Одно из решений, добавить метод, который будет возвращать текущий приоритет:

std::thread thread([](){ ... }, std::thread::priority::high_priority);

if (thread.priority() != std::thread::priority::high_priority) {
   ...
}

Не думаю, что неудача установки приоритета это критическая ошибка, что бы кидать исключения или не запускать поток на выполнение, в Linux такое часто происходит, если у программы нет прав root.

DymOK93 commented 2 years ago

Как вариант. Заодно можно сразу реализовать метод bool set_priority(std::thread::priority)

А на всех ли платформах можно установить потоку приоритет? Есть опасения насчет гибкости итогового решения...

maksimus1210 commented 2 years ago

Установка приоритета есть на всех ОС, но не на всех можно поднимать до высокого без привилегий. В Qt возможность есть устанавливать приоритет.

DymOK93 commented 2 years ago

Пока я вижу "полторы" проблемы:

  1. Вопрос привилегий. Но - по крайней мере на Windows - нужные права можно получить при создании потока средствами WinAPI.
  2. Нюансы с установкой приоритетов для потоков в ядре (да, речь о имплементации thread в несколько нестандартном окружении). Но это уже лично мои тараканы - практика показывает, что Комитет по стандартизации и С++ ядерщики в разных плоскостях находятся :)