Темы mingw-w64: posix против win32
Я устанавливаю mingw-w64 на Windows, и есть два варианта: потоки win32 и потоки posix. Я знаю, в чем разница между потоками win32 и pthreads, но я не понимаю, в чем разница между этими двумя вариантами. Я сомневаюсь, что если я выберу потоки posix, это не даст мне вызвать функции WinAPI, такие как CreateThread.
Кажется, что эта опция указывает, какой API потоков будет использоваться какой-либо программой или библиотекой, но чем? GCC, libstdC++ или что-то еще?
Я нашел это: Какая разница между thread_posixs и thread_win32 в порте gcc окон?
Короче говоря, для этой версии mingw в выпуске threads-posix будет использоваться API posix и разрешено использование std::thread, а в thread-win32 будет использоваться API win32, и будет отключена часть std:: thread стандарт.
Хорошо, если я выберу потоки win32, std:: thread будет недоступен, но потоки win32 все равно будут использоваться. Но используется чем?
4 ответа
GCC поставляется с библиотекой времени выполнения компилятора (libgcc), которую он использует (помимо прочего) для обеспечения низкоуровневой абстракции ОС для многопоточной связанной функциональности на языках, которые он поддерживает. Наиболее актуальным примером является C++11 в libstdC++. <thread>
, <mutex>
, а также <future>
, которые не имеют полной реализации, когда GCC создается с внутренней моделью потоков Win32. MinGW-w64 предоставляет winpthreads (реализацию pthreads поверх многопоточного API Win32), которую GCC затем может связать, чтобы включить все необычные функции.
Я должен подчеркнуть, что эта опция не запрещает вам писать любой код, который вы хотите (он абсолютно не влияет на то, какой API вы можете вызывать в своем коде). Он отражает только то, что библиотеки GCC (libgcc/libstdC++/...) используют для своей функциональности. Предостережение, цитируемое @James, не имеет ничего общего с внутренней моделью потоков GCC, а скорее с реализацией Microsoft CRT.
Подвести итоги:
posix
: включить функции многопоточности C++11/C11. Заставляет libgcc зависеть от libwinpthreads, так что даже если вы напрямую не вызываете pthreads API, вы будете распространять библиотеку winpthreads. Нет ничего плохого в распространении еще одной DLL с вашим приложением.win32
: Нет многопоточности C++11.
Ни один из них не влияет на любой пользовательский код, вызывающий Win32 API или API pthreads. Вы всегда можете использовать оба.
Части времени выполнения GCC (в частности, обработка исключений) зависят от используемой модели потоков. Итак, если вы используете версию среды выполнения, которая была построена с потоками POSIX, но решили создать потоки в своем собственном коде с помощью Win32 API, у вас, вероятно, будут проблемы в какой-то момент.
Даже если вы используете многопоточную версию Win32, вам, вероятно, не следует напрямую вызывать API-интерфейсы Win32. Цитата из MinGW FAQ:
Поскольку MinGW использует стандартную библиотеку времени выполнения Microsoft C, которая поставляется вместе с Windows, вы должны быть осторожны и использовать правильную функцию для создания нового потока. В частности,
CreateThread
Функция не будет правильно устанавливать стек для библиотеки времени выполнения C. Вы должны использовать_beginthreadex
вместо этого, который (почти) полностью совместим сCreateThread
,
Обратите внимание, что теперь можно использовать некоторые из C++11 std::thread в режиме потоков win32. Эти адаптеры только для заголовков работали для меня из коробки: https://github.com/meganz/mingw-std-threads
Из истории ревизий, похоже, есть недавняя попытка сделать это частью среды выполнения mingw64.
@rubenvb ответ полностью верен, используйте компилятор mingw posix, если вы хотите использовать
std::thread
,
std::mutex
и т.д. Для всех, кто использует CMake, вот пример:
set(CMAKE_CXX_STANDARD 17) # or 20 if you want..
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(THREADS_PREFER_PTHREAD_FLAG ON)
set(TOOLCHAIN_PREFIX x86_64-w64-mingw32)
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc-posix)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++-posix)
set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)
set(CMAKE_FIND_ROOT_PATH
/usr/${TOOLCHAIN_PREFIX}
)
Идеально подходит для кросс-компиляции приложений Linux в Windows.
Подсказка: для людей, которые используют GTK3 и хотят кросс-компилировать свое приложение GTK для Windows. Возможно, вы захотите загрузить пакет Mingw Windows GTK, загруженный и упакованный с msys2.org, поэтому вам не нужно: https://gitlab.melroy.org/melroy/gtk-3-bundle-for-windows