The correct way to check thread execution?

I use multithreading in my application with _beginthread and now, to wait until all threads are completed. I have global bools that set to true as each thread terminates, so until then I am in the while loop. Should there be a cleaner way to do this?

thank

+5
source share
6 answers

You can use WaitForMultipleObjects to wait for the threads to finish in the main thread.

+8
source

_beginthreadex . _beginthread _beginthreadex , , _beginthread, , , .

Win32, WaitForSingleObject WaitForMultipleObjects.

, _beginthreadex, CloseHandle().

+2

, , . , , . std::set<HANDLE> . Windows:

  • WaitForSingleObject
  • WaitForMultipleObjects

, . , :

std::set<HANDLE> thread_handles; // contains the handle of each worker thread
while (!thread_handles.empty()) {
    std::set<HANDLE> threads_left;
    for (std::set<HANDLE>::iterator cur_thread=thread_handles.begin(),
                                    last=thread_handles.end();
         cur_thread != last; ++cur_thread)
    {
        DWORD rc = ::WaitForSingleObject(*cur_thread, some_timeout);
        if (rc == WAIT_OBJECT_0) {
            ::CloseHandle(*cur_thread); // necessary with _beginthreadex
        } else if (rc == WAIT_TIMEOUT) {
            threads_left.add(cur_thread); // wait again
        } else {
            // this shouldn't happen... try to close the handle and hope
            // for the best!
            ::CloseHandle(*cur_thread); // necessary with _beginthreadex
        }
    }
    std::swap(threads_left, thread_handles);
}

WaitForMultipleObjects , . ; WAIT_MAXIMUM_OBJECTS . . ;)

DWORD large_timeout = (5 * 60 * 1000); // five minutes
std::set<HANDLE> thread_handles; // contains the handle of each worker thread
std::vector<HANDLE> ary;         // WaitForMultipleObjects wants an array...
while (!thread_handles.empty()) {
    ary.assign(thread_handles.begin(), thread_handles.end());
    DWORD rc = ::WaitForMultipleObjects(std::min(ary.size(), WAIT_MAXIMUM_OBJECTS),
                                        &ary[0], FALSE, large_timeout);
    if (rc == WAIT_FAILED) {
        // handle a failure case... this is usually something pretty bad
        break;
    } else if (rc == WAIT_TIMEOUT) {
        // no thread exited in five minutes... this can be tricky since one of
        // the threads beyond the first WAIT_MAXIMUM_OBJECTS may have terminated
    } else {
        long idx = (rc - WAIT_OBJECT_0);
        if (idx > 0 && idx < ary.size()) {
            // the object at `idx` was signaled, this means that the
            // thread has terminated.
            thread_handles.erase(ary[idx]);
            ::CloseHandle(ary[idx]); // necessary with _beginthreadex
        }
    }
}

, . , , WaitForMultipleObjects(ary.size(), &ary[0], TRUE, INFINITE). , , , , ary.size() MAXIMUM_WAIT_OBJECTS.

, , . , . boost::thread_group.

+1

Windows , . Visual ++ MFC. , MFC, Boost. , Windows API.

0

You can use boost :: thread objects. Call the joinobject and it will wait for the thread to complete.

0
source

All Articles