1

I am having some trouble with multi threaded c++ code on windows.

class test
{
public:
    bool flag;
    test() {flag=true;}
    void start_do(){while(flag) puts("doing...");}
    void stop_do() {flag=0;}
}

int main()
{
    test t;
    HANDLE h=CreateThread(0,0,(LPTHREAD_START_ROUTINE)t.start_do,0,1,0);
    Sleep(5000);
    t.stop_do();
    return 0;
}

I want to change the doing state with the flag. But it doesn't work. Could someone give me some help!

Floris Velleman
  • 4,848
  • 4
  • 29
  • 46
zdczdcc
  • 119
  • 2
  • 14
  • You're missing a semicolon after your class declaration. –  Mar 16 '16 at 10:34
  • 2
    Don't do it this way. There are C++-specific ways to create threads, like the [thread](https://msdn.microsoft.com/en-us/library/hh920601.aspx) class, available since VC++ 2012. Your code will be incompatible even with Microsoft's own libraries that *do* use `` – Panagiotis Kanavos Mar 16 '16 at 10:34
  • A member function isn't a valid LPTHREAD_START_ROUTINE. You would need to use a static or free function for that. –  Mar 16 '16 at 10:36
  • Also you would need to pass a pointer to an object to CreateThread(). –  Mar 16 '16 at 10:37

2 Answers2

5

The entire code does not make much sense.

first of all, Windows API is a C api. C has no knowing of what a class or method is. C only knows global functions. so passing member function is the first mistake.

secondly, the member function you provided does not look like what CreateThread expects to! you should supply a function with the signature DWORD __stdcall (void*), you function does not look like that at all. casting it by force will only make more troubles.

thirdly, the way to pass a member function is with the sintax &ClassName::functionName. writing object.function means nothing.

finally, C++ has much simpler way of creating threads , and using them as objects, not handles:

test t;
std::thread t([&]{ t.start_do(); });

now, I don't recommend using winapi for creating threads unless you have really good reason why (like specifying the stack size, and if the stack memory is reserved or commited, etc.)

for the sake of the disscution here, the way to make you example to work is by "flattening" the object into void* and re-cast it back inside some global function:

DWORD __stdcall callStartDo(void* pObject){
   auto object = reinterpret_cast<test*>(pObject);
   if (object){
     object->start_do();
   } 
   return 0U;
} 

//...
test t;
unsigned long threadID = 0U;
CreateThread(nullptr,0U,&callStartDo,&t,0,&threadID);

and again, this examle shows how to do it only, I strongly advice using std::thread instead. (look at how much overhead is involved vs. the C++ way!)

David Haim
  • 25,446
  • 3
  • 44
  • 78
  • `static_cast` is better than `reinterpret_cast`. `if (object)` is cargo-cult. `CreateThread` should not be used in C++ programms even when c++11 is unvailable - `beginthreadex_` should be used instead. Unneccessary initialization of `threadID`. – SergeyA Mar 16 '16 at 13:09
  • @SergeyA I think it's pathetic that you're following *every* answer I make and downvote it automatically. seriously, find a life. and seriously, I did emphasized how much should one use `std::thread` and how much the snippet is for the sake of the discussion. you basically HAVE NO REASON downvoting it. I don't know what exactly is your goal, but seriously, STOP. – David Haim Mar 16 '16 at 13:10
  • No, I think you really think too much of me :) I do not even know who you are, I do not remember people nicjnames. I read answers on the topic I am interested in, and downvote wrong ones. My honest word, I have no idea who you are, and I am certainly not following you. – SergeyA Mar 16 '16 at 13:12
  • I did. there is one big problem (CreateThread vs beginthreadex_ is a no-no-no) and several cargo-cult things which simply should be banished. – SergeyA Mar 16 '16 at 13:15
  • But you had no problem suggesting `std::thread`. And you did provide a sample code. – SergeyA Mar 16 '16 at 13:16
  • why would I suggest any API out there that creates a thread?! I showed hom the preferable way to do it, not without explaining how to make his original to work! – David Haim Mar 16 '16 at 13:18
  • As it stands right now, your answer is damaging, in contains code that can be copied into other project and this code is dangerous. You might either edit it to remove dangerous code, or you might live with my downvote. The choice is yours. – SergeyA Mar 16 '16 at 13:23
  • Not sure what you mean. Do you mean a typo I had in the function name? It is alredy fixed. – SergeyA Mar 16 '16 at 13:27
  • so basically, if it's not part of the standard it's dangerous and should be bad in all cases, right? in this case, please tell how am I supposed to write something which has a GUI inside, networking , JIT, VM and basically anything which the standard doesn't cover? let's throw the JVM out of the window, it's bad! it doesn't use the standard! let's throw the CLR out the window, it uses WinApi behind the scens! let's throw HHVM, dear lord, it calls POSIX! firefox?! how dare you use winsock?! its C API and dangerous! – David Haim Mar 16 '16 at 13:28
  • It is you who are not reading. it is not dangerous because it is not part of the standard. It is dangerous because Microsoft says so. They explicitly say that due to the way VC C++ runtime works, `CreateThread` should not be used in C++ programms. Instead, `beginthreadex_` is to be used. Both functions are non standard, but one is said not to be used by the documentation of your OS. – SergeyA Mar 16 '16 at 13:45
  • you just google it now in order to support your downvote. in the last few weeks, you have downvoted every answer you saw that was written by me. sorry, my logo is pretty much destinguishable. your arguments are weak. – David Haim Mar 16 '16 at 13:50
  • No, I have known it for at least 15 years. You see, I am a professional developer. And no, I do not follow you and have no idea what your logo looks like (had to scroll up to see it, forgot immediately). If I am downvoting your answers, it means one thing only - they are wrong. This is the only reason I ever downvote an answer - if I belive they are wrong. Sometimes I am mistaken, in this case, I correct my errors after meaningful conversation with the poster. In this case, I see a conspiracy person. Really, world is not about you. – SergeyA Mar 16 '16 at 13:55
  • @SergeyA: "Dangerous". lol. For over 10 years, the **worst** `CreateThread` can cause is a small memory leak when the thread terminates. If you link against a CRT DLL (rather than embedding it in your binary) even that small "danger" disappears. Read http://stackoverflow.com/questions/331536/windows-threading-beginthread-vs-beginthreadex-vs-createthread-c and the documents linked there. – conio Mar 20 '16 at 15:16
  • @David Haim,thanks a lot for your help!I would receive your advice in my project. – zdczdcc Mar 22 '16 at 09:42
0

You can use <thread> though. cplusplus.com - <thread>

It can be a little hard to understand threads,cause I did.
But it will be easy if you look at the link I added.I think.