Какой вариант лучше для создания (и управления) потоков в Visual С++: С++ 11 std::thread
или WinAPI
функции (например, CreateThread
, _beginthreadex
и т.д.) и почему?
С++ 11 std:: thread vs windows CreateThread
Ответ 1
Портативность
std::thread
является новичком в стандарте С++ 11 - с ним вы можете написать переносимый код на С++ для компиляторов, поддерживающих С++ 11. Вы можете почувствовать future
в нем.
Он основан на boost::thread
, который поддерживает более старые компиляторы, не поддерживающие С++ 11, что упрощает перенос на другие платформы.
Если вам нужно использовать специальные трюки платформы, std::thread::native_handle
- это путь.
CreateThread
специфичен для WinAPI, это подразумевает запись непереносимого кода. Кроме того, этот API довольно старый и более неудобный для использования.
RAII
WinAPI - это API C, который не поощряет современный С++ хороший практика. Каждый создающий примитив, вы должны впоследствии уничтожить вручную.
Это не относится к библиотеке потоков в С++ 11, что упрощает запись абстракций более высокого уровня. Пока std::thread
все еще довольно низкоуровневый (либо ваш .join()
, либо .detach()
ваш поток, либо деструктор потока завершит вашу программу), библиотека потоков С++ 11 имеет std::lock_guard
и другие классы блокировки для поддержки RAII для мьютексов.
В то время как С++ 11 имеет некоторые абстракции более высокого уровня, такие как std::async
для запуска функций асинхронно, он не предоставляет других абстракций, таких как threadpool, поэтому вы можете использовать другие библиотеки.
Тип безопасности
WinAPI может вызывать только указатели функций с определенной сигнатурой - которые подвержены ошибкам, связанным с безопасностью типа, временем жизни объектов и ошибкой памяти.
std::thread
может вызывать любой вызываемый объект:
// call free-standing function in a separate thread
std::thread first(func);
// call free-standing function with arguments (1, 2), in a separate thread
std::thread second(func, 1, 2);
// call static member function in a separate thread
std::thread third(&A::static_memfun);
// call non-static member of a temporary in a separate thread
std::thread fourth(&A::memfun, A());
//call std::function in a separate thread
std::function<void(int)> callback = std::bind(func, 1, _1);
std::thread fifth(callback, 2);
// call a function object
Functor f;
std::thread sixth(f);
TL; DR. Нет смысла использовать потоки WinAPI в качестве основного механизма потоков в новом коде на С++.
Ответ 2
Кросс-платформенность - небольшое преимущество. Настоящее преимущество в интерфейсе. std::thread
предлагает RAII-гарантии по очистке потока и поддерживает произвольные аргументы объектных объектов, а не только указатели на функции. std::thread
- это оболочка С++ 11 на CreateThreadEX, и именно по этой причине.
Как примечание, std:: thread - ужасный, ужасный API. Если вы сами создаете темы, вы, вероятно, ошибаетесь. Используйте настоящий API для потоковой передачи, такой как Intel TBB или Microsoft PPL, которые значительно превосходят ужасные std::thread
и еще хуже, чем CreateThreadEx. std::thread
: "Привет, ребята, я предложил вам кросс-платформенный mmap
, чтобы вы могли написать свой собственный malloc
сверху, наслаждайтесь!".
Ответ 3
Вероятно, вы должны использовать std:: thread.
std:: thread является частью (нового) стандарта и переносится.
Если вы не ориентируетесь только на Windows, и вам нужно взаимодействовать с вашими потоками с помощью WinAPI, std:: thread - это путь.