mingw std::thread с Windows API

Я начал использовать С++ 11 std::thread (mingw 4.8), пока все хорошо. Я столкнулся с ситуацией с перекрывающимся вводом-выводом, когда sleepEx использовался для перевода потока в состояние ожидания с возможностью оповещения. Это работало довольно хорошо, пока не пришлось использовать QueueUserAPC, что вернуло «ошибку недопустимого дескриптора».

После некоторых поисков выяснилось, что std::thread использует библиотеку pthread под Windows.

Есть ли способ использовать вызовы Windows API, которые ожидают дескриптор потока с std::thread? Или мне нужно придерживаться потоков Windows для перекрывающихся операций ввода-вывода?


person Waldorf    schedule 08.10.2013    source источник
comment
Я не знаком с Windows API, но похоже, что вы смешиваете многопоточность Windows API с C++11 std::threads, а поскольку mingw 4.8 использует под капотом pthreads, это приводит к проблемам. Это верно? Вероятно, лучше использовать только один API потоковой обработки, даже если бы существовал способ заставить mingw std::threads использовать потоки Windows API вместо pthreads.   -  person Nicu Stiurca    schedule 08.10.2013


Ответы (3)


Есть ли способ использовать вызовы Windows API, которые ожидают дескриптор потока с помощью std::thread ?

Нет, потому что std::thread в вашей сборке MinGW не реализован с точки зрения дескрипторов потоков. Изменить: это так, но косвенно, см. ответ rubenvb о том, как получить собственный дескриптор потока из pthread_t, и вы сможете использовать std::thread::native_handle() для получения pthread_t.

Никто не реализовал в GCC необходимую поддержку библиотеки потоков C++11 для прямого использования собственных потоков Windows.

У меня было несколько идей для новой модели рекламы, которая будет реализована с точки зрения собственных мьютексов и условных переменных. Это позволит вам вызвать std::thread::native_handle(), чтобы получить базовый дескриптор потока для использования с Windows API.

Я дошел до перестройки GCC с применением моих изменений, но не смог их протестировать. Мои предложения почти не вызвали интереса и никаких предложений помощи от участников MinGW, поэтому, поскольку я не пользователь Windows, а работа над Windows и сборка MinGW были настолько болезненными и разочаровывающими, что я сдался. Я должен разместить свои изменения где-нибудь в Интернете, чтобы кто-то, у кого больше терпения, чем у меня, мог однажды закончить работу.

person Jonathan Wakely    schedule 08.10.2013
comment
Я следил за вашим обсуждением с К. Франком, который активно участвует в списке рассылки MinGW-w64. Он реализовал код оболочки gthread только для Vista+, сделав std::thread доступным для собственных примитивов Win32. Как вы сказали, это неприемлемо без новой модели многопоточности, позволяющей использовать XP-совместимые наборы инструментов. Я знаю, что это плохое место для обсуждения, но можно ли сделать выбор между двумя реализациями во время выполнения (одна медленная для XP, другая быстрая для более новых версий)? Я уверен, что где-то в GCC есть dload, почему бы и нет? - person rubenvb; 08.10.2013
comment
Привет, Рубен, рад, что к этому есть интерес. В настоящее время невозможно выбрать во время выполнения, потому что оболочки gthread являются либо встроенными функциями, либо скомпилированы в libgcc, а используемый код выбирается при настройке GCC. Теоретически я предполагаю, что новая модель gthread Vista+ может иметь вызов libgcc в какую-то другую DLL, и могут быть альтернативные реализации этой DLL. Это потребует довольно много изменений, но я был бы готов помочь внести это в GCC (вероятно, не раньше февраля/марта следующего года) - person Jonathan Wakely; 08.10.2013

Чтобы решить вашу проблему, MinGW-w64 winpthreads (используемая вами реализация pthreads), точно так же, как pthreads-win32 позволяет получить собственный дескриптор потока Win32 для pthread:

void * pthread_gethandle (pthread_t t);

Обратите внимание, что в настоящее время это недокументированная функция.

Соответствующая функция в pthreads-win32:

HANDLE pthread_getw32threadhandle_np(pthread_t thread);

Могу поспорить, что это заставит ваше смешивание двух работать или, по крайней мере, выявит некоторые ошибки в winpthreads, которые можно исправить. В последнем случае сообщите о них MinGW-w64.

Если вышеуказанное возвращает недопустимый дескриптор, лучше всего спросить об этом в общедоступном списке рассылки MinGW-w64 (сначала подпишитесь, иначе вам придется ждать ручной модерации, что глупо).

person rubenvb    schedule 08.10.2013
comment
Хорошо, тогда объединение этой функции с std::thread::native_handle() может сработать. - person Jonathan Wakely; 08.10.2013
comment
К сожалению, pthread.h, включенный в GCC4.8, не включает pthread_getw32threadhandle_np. - person Waldorf; 09.10.2013
comment
@Уолдорф, хорошо. Кажется, я нашел тестовый файл pthreads-win32 внутри исходного дерева winpthreads, используя его. Как насчет pthread_gethandle, который кажется возвратить HANDLE. Обратите внимание, что эта функция является деталью реализации. - person rubenvb; 09.10.2013
comment
Спасибо! Хотя это кажется недокументированной функцией, она работает так, как ожидалось. При передаче native_handle он возвращает допустимый дескриптор потока Windows, и все работает так, как ожидалось. - person Waldorf; 09.10.2013

Уже существует нативная реализация примитивов std::thread и sync для win32, см.:

https://github.com/meganz/mingw-std-threads

Это библиотека только для заголовков, которая работает с любой версией MinGW, имеющей надлежащую языковую поддержку для C++11.

person Alexander Vassilev    schedule 11.12.2014