Question

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);
}
Was it helpful?

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()

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top