Evaldas Jankauskas
Evaldas Jankauskas

Reputation: 17

Why Sleep() on Main function stop all threads?

Why does Sleep() stop all created threads? I want to create a thread but keep the Main function in sleep until the thread finishes.

bool _finished = false;

void testcount(void *p){
 int i = 0;
 while(i<=30){
  i++;
  std::cout<<i<<"\n";
  Sleep(1000);
 }
_finished = true;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved){
 HANDLE test = NULL;
 test = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)testcount, NULL, NULL, NULL);
 if(test)
  std::cout<<"test thread created";
 CloseHandle(test);

 while(!_finished)
  Sleep(1000);

return true;
}

I am trying it now like this, but the program just never finishes, because while with Sleep stops the thread. I don't want to return anything on Main while thread not finished. Any solution?

Upvotes: 0

Views: 1226

Answers (2)

Arne Vogel
Arne Vogel

Reputation: 6666

The new thread is blocked because your main thread does not leave DllMain, as described in Richard's answer.

Your code also contains a data race and has undefined behavior even after this deadlock is fixed. The new thread writes to _finished, the main thread reads from _finished, concurrently. You could try to use std::atomic<bool> instead of bool to fix this, assuming availability of C++11, or you could use Win32 primitives for thread synchronization.

Changes for standard solution using std::atomic<bool>:

#include <atomic>

std::atomic<bool> finished_{false};

// Rest remains the same

Upvotes: 1

Richard
Richard

Reputation: 108975

  1. Calls to DllMain are serialised by Win32.

  2. All new threads start by calling DllMain (with thread attach flag), and the call the method passed to CreateThread.

Therefore your thread is waiting to call DllMain, which cannot happen until your first thread leaves DllMain.

As commenter John Sheridan notes Raymond Chen's blog post from 2007 is a really good explanation.

PS. for correct C/C++ library initialisation you should be using _beginthread or _beginthreadex rather than CreateThread directly.

Upvotes: 4

Related Questions