Search code examples
c++multithreadingwindows-phone-7windows-runtimemanaged

How to execute c++ function in a parallel thread under WinRT?


I have a C++ code which uses _beginthreadex() Windows method to execute a function in a thread. Now I want to port it to WinRT component to include it in windows phone app. But windows phone does't support _beginthreadex(). How do I do it?

my function is:

bool doesWordAppearInDictionarry(char* word);

I have 4 cores on my computer so I want to execute 4 copies of this function in parallel (searching for 4 different words in the dictionary simultaneously).

I read (here) and (here) about Windows::System::Threading::WorkItemHandler, ThreadPool's and IAsyncAction But the supplied examples activate managed code and do not call a native function.

What I am looking for is a clean solution (minimal amount of lines of code) which will replace my current Windows Desktop code:

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);
}

Solution

  • Here is a short solution: Few lines of code that emulate _beginthreadex() using 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;
        }
    }
    

    This solution is based on stack overflow answer (here) which discusses (this) blog. The blog includes a full emulation of threads including the CreateThread() Win32 api, accessing threads while they are running and sharing memory between threads. My solution is a simplified case of the full emulator.

    P.s. The caller method must waid for the threads using WaitForSingleObjectEx() method and not WaitForSingleObject()