У меня есть код C ++, который использует метод Windows _beginthreadex () для выполнения функции в потоке. Теперь я хочу портировать его на компонент WinRT, чтобы включить его в приложение Windows Phone. Но Windows Phone не поддерживает _beginthreadex (). Как мне это сделать?
моя функция:
bool doesWordAppearInDictionarry(char* word);
У меня есть 4 ядра на моем компьютере, поэтому я хочу выполнить 4 копии этой функции параллельно (поиск 4 разных слов в словаре одновременно).
Я читаю (Вот) а также (Вот) около Windows::System::Threading::WorkItemHandler
, ThreadPool
и IAsyncAction
Но приведенные примеры активируют управляемый код и не вызывают нативную функцию.
То, что я ищу, — это чистое решение (минимальное количество строк кода), которое заменит мой текущий код Windows Desktop:
for (int i=0; i<4; i++){
tInfo[i].id = (HANDLE)_beginthreadex( NULL, stack_size, doesWordAppearInDictionarry,tInfo, 0, word[i]);
}
for (int i=0; i<4; i++){
WaitForSingleObject( tInfo[i].id, INFINITE );
CloseHandle(tInfo[i].id);
}
Вот короткое решение: несколько строк кода, эмулирующих _beginthreadex () с использованием WinRT api.
using namespace Platform;
using namespace Windows::System::Threading;
_Use_decl_annotations_ HANDLE WINAPI _beginthreadex(LPSECURITY_ATTRIBUTES unusedThreadAttributes, SIZE_T unusedStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD unusedThreadId){
// Create a handle for the new thread.
HANDLE threadHandle = CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
if (!threadHandle)
return nullptr;
try{
auto workItemHandler = ref new WorkItemHandler([=](IAsyncAction^){
lpStartAddress(lpParameter);
SetEvent(threadHandle); // Signal that the thread has completed (assuming this handle was not destroyed by the caller due to time-out).
}, CallbackContext::Any);
ThreadPool::RunAsync(workItemHandler, WorkItemPriority::High, WorkItemOptions::TimeSliced);
return threadHandle; // Return the handle to the caller (he can wait for this handle until thread terminates).
}
catch (...){
CloseHandle(threadHandle); // Clean up if thread creation fails.
return nullptr;
}
}
Это решение основано на ответе переполнения стека (Вот) который обсуждает (этот) блог. Блог включает в себя полную эмуляцию потоков, включая API-интерфейс Win32 CreateThread (), доступ к потокам во время их работы и совместное использование памяти между потоками. Мое решение — упрощенный случай полного эмулятора.
Постскриптум Метод вызывающей стороны должен ждать потоков, используя WaitForSingleObjectEx(
) метод а не WaitForSingleObject()
Других решений пока нет …