1

I am trying to create and execute a thread using Windows CreateThread API. am seeing that running the program gives non-deterministic behavior. I am seeing from the output of the program that sometimes the thread method "my" gets executed and sometimes not. What might be the reason for this? The program is very simple as shown below. Also what should dwThreadID be initialized with. Should it be 0 or any integer value? PS:Compiling in Visual Studio.

#include "stdafx.h"
#include <iostream>  
#include <windows.h>  
using namespace std;

// DWORD WINAPI   
DWORD  WINAPI my (LPVOID lpParam ) {  
    for (int i = 0; i < 5;i++){  
        cout << "I am ";  
    } 
    return 0; 
} 

int main()  
{
    DWORD dwThreadID = 0;   
    DWORD dwThrdParam = 0;  
    HANDLE h = NULL; 
    h = CreateThread(
            NULL,              // default security
            0,                 // default stack size
            my,        // name of the thread function
            0,              // no thread parameters
            0,                 // default startup flags
            &dwThreadID); 
     if (h == NULL){  
         cout <<"It is null";
     }      
    cout << " BBBB" << endl ;  
    CloseHandle(h); 
    cout << "BBBB "; 
    return 0;  
}
Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
user496934
  • 3,822
  • 10
  • 45
  • 64

3 Answers3

5

I am seeing from the output of the program that sometimes the thread method "my" gets executed and sometimes not. What might be the reason for this?

Probably your main thread exits before your second thread is even executed. Place breakpoint after call to CreateThread.

Or even more cleaner wait, just wait for second thread using WaitForSingleObject. This effectively make your main thread waiting until "my" thread is done.

If CreateThread fails for some reason, you can call GetLastError right after CreateThread, it will give you ultimate answer.

Also what should dwThreadID be initialized with.

Quick look into MSDN yields following:

A pointer to a variable that receives the thread identifier.

rkosegi
  • 14,165
  • 5
  • 50
  • 83
  • Thanks for the answer. Probably your main thread exits before your second thread is even executed. It is working now after using WaitForSingleObject. – user496934 Mar 25 '16 at 07:18
4

It is indeterminate whether or not your thread executes. The main thread creates it and then terminates the program. The following may happen:

  • The thread may execute before the main thread terminates.
  • The program may terminate before the thread executes.
  • The thread may partially execute and be terminated when the program terminates.

You would need to add synchronization in order to be sure that the thread reaches completion. Pass the thread handle to WaitForSingleObject.

Your program does not check for errors. CreateThread returns NULL when it fails. If that happens, and only if that happens, call GetLastError for information as to why the function failed. If you add a call to WaitForSingleObject then you should check its return value for errors as described by the documentation.

What should dwThreadID be initialized with?

It does not need to be initialized because CreateThread guarantees it will be assigned if CreateThread succeeds.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
0

Firstly do not use CreateThread it is intended for library providers. Use beginthreadex or std::thread

The likely behavior, is that the thread always runs, but it's output is being overwritten. This is because there is no synchronisation.

Check the return code and GetLastError

The value of dwThreadid does not matter

mksteve
  • 12,614
  • 3
  • 28
  • 50
  • Just to note that by using `beginthreadex`, you make your program depending on MSVCRT. – rkosegi Mar 25 '16 at 07:00
  • 1
    @mksteve No it is not. The runtime has been compatible with CreateThread for many years. – David Heffernan Mar 25 '16 at 07:11
  • 1
    From msdn "A thread in an executable that calls the C run-time library (CRT) should use the _beginthreadex and _endthreadex functions for thread management rather than CreateThread and ExitThread; this requires the use of the multithreaded version of the CRT. If a thread created using CreateThread calls the CRT, the CRT may terminate the process in low-memory conditions.". Functions with TLS (e.g. strtok) create TLS structures. Using CreateThread causes this to be delayed till use. Causing `exit` calls. begin thread adds code at end to tidy up TLS memory – mksteve Mar 25 '16 at 07:38
  • 2
    @mksteve That documentation is out of date and has not been relevant for years. The limitation was incompatible with the system threadpool and so the CRT was changed. http://stackoverflow.com/questions/2100589/beginthread-vs-createthread This is one of those cargo cult beliefs that simply won't go away. I fully expect to be here 20 years from now having the same conversation with our children! – David Heffernan Mar 25 '16 at 08:15