С++ 11 std:: thread vs windows CreateThread

Какой вариант лучше для создания (и управления) потоков в Visual С++: С++ 11 std::thread или WinAPI функции (например, CreateThread, _beginthreadex и т.д.) и почему?

Ответ 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 - это путь.