C ++ 11: std :: thread объединяется?

В C ++ 03 я использовал pthread со встроенным пулом потоков, который всегда поддерживал работу нескольких потоков (так как pthread_create медленно), таким образом, я смог запустить потоки для небольших задач, не думая о проблемах производительности.

Теперь в C ++ 11 мы имеем std::thread, Я предполагаю, что стандарт ничего не говорит о конкретной реализации, поэтому мой вопрос касается реализаций стандартной библиотеки. Они вообще выбирают объединенный подход, где строительство std::threads дешево (и, например, не звонит pthread_create на posix), или будет std::thread просто быть оберткой?

Другими словами, пул потоков все еще рекомендуется в C ++ 11, или я должен просто создать std::thread когда мне нужно и оставить производительность до стандартной библиотеки?

37

Решение

В общем-то, std::thread должна быть минимальной оболочкой для базового системного примитива. Например, если вы на pthread платформу, вы можете проверить с помощью следующей программы, что независимо от того, сколько потоков вы создаете, все они создаются с уникальным pthread_t идентификаторы (что подразумевает, что они созданы на лету, а не заимствованы из пула потоков):

#include <assert.h>
#include <mutex>
#include <set>
#include <thread>
#include <vector>

#include <pthread.h>

int main() {
std::vector<std::thread> workers;
std::set<long long> thread_ids;
std::mutex m;
const int n = 1024;

for (int i = 0; i < n; ++i) {
workers.push_back(std::thread([&] {
std::lock_guard<std::mutex> lock(m);
thread_ids.insert(pthread_self());
}));
}
for (auto& worker : workers) {
worker.join();
}
assert(thread_ids.size() == n);

return 0;
}

Так что пулы потоков все еще имеют смысл. Тем не менее, я видел видео, где члены комитета C ++ обсуждали пулы потоков относительно std::async (IIRC), но я не могу найти это прямо сейчас.

23

Другие решения

std::thread это поток исполнения. Период. Откуда оно берется, как оно туда попадает, есть ли какой-то пул «реальных» потоков и т. Д., Все это не имеет отношения к стандарту. Пока это действует как нить, это может быть std::thread,

Теперь шансы хороши, что std::thread это реальный поток ОС, а не что-то извлеченное из пула потоков или чего-то еще. Но C ++ 11 теоретически позволяет std::thread быть реализованным как нечто извлеченное из пула.

11

std::thread должен быть очень дешевым с точки зрения затрат на абстракцию, это вещи низкого уровня. Насколько я понимаю, реализации стандартных библиотек, вероятно, собираются просто как можно точнее обернуть базовые механизмы ОС, чтобы можно было предположить, что накладные расходы на создание потоков будут аналогичными или эквивалентными.

Я не знаю о каких-либо конкретных реализациях, но это мое понимание из вторых рук от чтения C ++ параллелизм в действии что стандарт предлагает использовать наиболее эффективный метод. Автор, конечно, думал, что стоимость будет более или менее незначительной по сравнению с DIY.

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

В принципе, я не думаю, что есть ответ на ваш вопрос напрямую, потому что он просто не указан. Хотя мне кажется, что мы с большей вероятностью увидим очень тонкие реализации-оболочки, я не думаю, что авторам библиотек запрещено использовать пулы потоков, если это дает преимущества в эффективности.

5

Во-первых, как вы упомянули, стандарт C ++ в основном не определяет реализацию библиотеки.
Но реализатор стандартной библиотеки C ++ должен подчиняться правилу «как будто».

Например, это означает, что конструктор std::thread должен вести себя как будто Новый поток создан, будь то тонкая оболочка базового API или эффективная реализация, такая как пул потоков. (здесь «поток» означает абстрактный нить исполнения в спецификации C ++ 11, а не конкретная нить нативной ОС)

О реализации пула потоков;

  • Компилятор и библиотека C ++ должны правильно обрабатывать специфичные для потока C ++ ресурсы (т.е. thread_local переменная), и они должны работать вместе во время выполнения.
  • Даже если вышеуказанное условие выполнено, кажется невозможным совместная работа с ресурсами потоков, специфичными для ОС (TLS для Windows, TSS для pthread и т. Д.).

Итак, я предполагаю, что большинство std::thread реализация — это просто оболочка базового API потоков.

2
По вопросам рекламы [email protected]