Josh Posted October 12, 2011 Share Posted October 12, 2011 I am not new to multithread programming, but I have never done it in C++. I want to create a thread to execute a function, and be able to tell when the thread is finished. The code should run on Windows and OSX. If it can run on Android and iOS, that's great, but I don't expect it to. Where can I find a simple example that shows how to do this? Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Canardia Posted October 12, 2011 Share Posted October 12, 2011 I have used this as a reference: https://computing.llnl.gov/tutorials/pthreads/ MinGW comes with pthreads library, not sure about Visual Studio, but you can get it for it too, for example from here: http://sourceware.org/pthreads-win32/ Alternatively you could also use boost::thread class, which is also standard: http://www.boost.org/doc/libs/1_47_0/doc/html/thread.html Quote ■ Ryzen 9 ■ RX 6800M ■ 16GB ■ XF8 ■ Windows 11 ■ ■ Ultra ■ LE 2.5 ■ 3DWS 5.6 ■ Reaper ■ C/C++ ■ C# ■ Fortran 2008 ■ Story ■ ■ Homepage: https://canardia.com ■ Link to comment Share on other sites More sharing options...
Josh Posted October 12, 2011 Author Share Posted October 12, 2011 I got started with win32 threads. I think I'd rather use my own class and just use macros to control the different behavior than to use something like Boost. How can I check the status of a thread? I need to be able to tell if a thread is still running. See Thread::GetState(): Thread.h #include "../le3.h" #ifdef WINDOWS namespace win32 { #include <windows.h> } #endif namespace le3 { const int THREAD_RUNNING = 1; const int THREAD_FINISHED = 0; const int THREAD_PAUSED = 2; const int THREAD_READY = 3; class Thread { public: Object* result; #ifdef WINDOWS HANDLE id; #endif Thread(); ~Thread(); virtual bool Resume(); virtual bool Pause(); virtual int GetState(); virtual Object* GetResult(); }; Thread* CreateThread_(Object* EntryPoint(Object* o), Object* o=NULL); } Thread.cpp #include "../le3.h" namespace le3 { Thread::Thread() : result(NULL) { #ifdef WINDOWS id = 0; #endif } Thread::~Thread() { #ifdef WINDOWS if (GetState()!=THREAD_FINISHED) { TerminateThread(id,0); } #endif } bool Thread::Pause() { #ifdef WINDOWS if (SuspendThread(id)!=-1) return true; #endif } bool Thread::Resume() { #ifdef WINDOWS if (ResumeThread(id)!=-1) return true; #endif } int Thread::GetState() { #ifdef WINDOWS #endif return 0; } Object* Thread::GetResult() { if (GetState()!=THREAD_FINISHED) return NULL; return result; } Thread* CreateThread_(Object* EntryPoint(Object* o),Object* o) { Thread* thread = new Thread; #ifdef WINDOWS thread->id = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)EntryPoint,NULL,CREATE_SUSPENDED,NULL); if (!thread->id) { delete thread; return NULL; } #endif return thread; } } Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Josh Posted October 12, 2011 Author Share Posted October 12, 2011 Eh, I got it figured out. Here's a nice little thread class if you need it: #include "../le3.h" #ifdef WINDOWS namespace win32 { #include <windows.h> } #endif namespace le3 { const int THREAD_RUNNING = 1; const int THREAD_FINISHED = 0; const int THREAD_PAUSED = 2; const int THREAD_READY = 3; class Thread { public: Object* result; #ifdef WINDOWS HANDLE id; int state; #endif Thread(); ~Thread(); virtual void Wait(); virtual bool Resume(); virtual bool Pause(); virtual int GetState(); virtual Object* GetResult(); }; Thread* CreateThread_(Object* EntryPoint(Object* o), Object* o=NULL); } #include "../le3.h" namespace le3 { Thread::Thread() : result(NULL) { #ifdef WINDOWS id = 0; state = THREAD_PAUSED; #endif } Thread::~Thread() { #ifdef WINDOWS if (GetState()!=THREAD_FINISHED) { TerminateThread(id,0); } #endif } bool Thread::Pause() { #ifdef WINDOWS if (SuspendThread(id)!=-1) { state = THREAD_PAUSED; return true; } else { return false; } #endif } bool Thread::Resume() { #ifdef WINDOWS if (ResumeThread(id)!=-1) { state = THREAD_RUNNING; return true; } else { return false; } #endif } int Thread::GetState() { #ifdef WINDOWS if (state==THREAD_RUNNING) { DWORD lpExitCode; if (GetExitCodeThread(id,&lpExitCode)==0) { //Function fails return THREAD_RUNNING; } else { if (lpExitCode==STILL_ACTIVE) { return THREAD_RUNNING; } else { return THREAD_FINISHED; } } } else { return state; } #endif return 0; } void Thread::Wait() { while (GetState()!=THREAD_FINISHED) { //win32::sleep(1); } } Object* Thread::GetResult() { if (GetState()!=THREAD_FINISHED) return NULL; return result; } Thread* CreateThread_(Object* EntryPoint(Object* o),Object* o) { Thread* thread = new Thread; #ifdef WINDOWS thread->id = CreateThread(NULL,4,(LPTHREAD_START_ROUTINE)EntryPoint,o,CREATE_SUSPENDED,NULL); if (!thread->id) { delete thread; return NULL; } #endif return thread; } } Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Canardia Posted October 12, 2011 Share Posted October 12, 2011 Why would you use a completely different approach for Windows, when you can use pthreads on all platforms? Anyway, with pthreads you can make thread states either with your own custom mutexed variables, or using the condition variables of threads: http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html Quote ■ Ryzen 9 ■ RX 6800M ■ 16GB ■ XF8 ■ Windows 11 ■ ■ Ultra ■ LE 2.5 ■ 3DWS 5.6 ■ Reaper ■ C/C++ ■ C# ■ Fortran 2008 ■ Story ■ ■ Homepage: https://canardia.com ■ Link to comment Share on other sites More sharing options...
Josh Posted October 12, 2011 Author Share Posted October 12, 2011 Because I am part of a vast conspiracy to keep Linux from becoming popular. Every little bit helps. Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Rick Posted October 12, 2011 Share Posted October 12, 2011 Member1592834 has blown his cover. Take him out. Is this related to the physics image you posted? Quote Link to comment Share on other sites More sharing options...
Scott Richmond Posted October 13, 2011 Share Posted October 13, 2011 Don't know if this is any help to anyone but I thought I'd just say that if one needs some sort of reliable, safe and easy inter-thread communication then ZeroMQ is an amazing library. Quote Programmer, Modeller Intel Core i7 930 @ 3.5GHz | GeForce 480 GTX | 6GB DDR3 RAM | Windows 7 Premium x64 Visual Studio 2008 | Photoshop CS3 | Maya 2009 Website: http://srichnet.info Link to comment Share on other sites More sharing options...
Josh Posted October 13, 2011 Author Share Posted October 13, 2011 In all seriousness, I want the lowest-level thread access possible so I can understand what is happening on all platforms completely. I also don't like compiling more libs into the engine because almost every time I do there is some little thing I have to fix. I take it I can just start calling pthread commands on Mac, iOS, and Android?: https://computing.llnl.gov/tutorials/pthreads/#CreatingThreads Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Scott Richmond Posted October 13, 2011 Share Posted October 13, 2011 ZMQ is really a communication pipeline that allows you to sidetrack the whole process of trying to interlock and all that other nasty thread stuff by just implementing fast message passing. Its really good if you're willing to design using their concepts. For pure threading, I might also just point you to TinyThread: http://sourceforge.net/projects/tinythread/ TinyThread++ is a minimalist, portable threading library for C++. It is modeled after the current C++0x standard (draft), implementing a subset thereof, and acts as a simple replacement library for compilers that lack support for C++0x. Kind of sounds like the wrapper class you're making now. Quote Programmer, Modeller Intel Core i7 930 @ 3.5GHz | GeForce 480 GTX | 6GB DDR3 RAM | Windows 7 Premium x64 Visual Studio 2008 | Photoshop CS3 | Maya 2009 Website: http://srichnet.info Link to comment Share on other sites More sharing options...
Canardia Posted October 13, 2011 Share Posted October 13, 2011 pthreads is part of GNU C++, so it should be available on all platforms. You just compile a program with: g++ -lpthread demo1.cpp Quote ■ Ryzen 9 ■ RX 6800M ■ 16GB ■ XF8 ■ Windows 11 ■ ■ Ultra ■ LE 2.5 ■ 3DWS 5.6 ■ Reaper ■ C/C++ ■ C# ■ Fortran 2008 ■ Story ■ ■ Homepage: https://canardia.com ■ Link to comment Share on other sites More sharing options...
TheoLogic Posted October 14, 2011 Share Posted October 14, 2011 C++11 has threading facilities, so I honestly think you are wasting your time to reinvent this... Quote Follow me Link to comment Share on other sites More sharing options...
Scott Richmond Posted October 14, 2011 Share Posted October 14, 2011 C++11 has threading facilities, so I honestly think you are wasting your time to reinvent this... I think you mean C++0x. But you're correct. Its why I mentioned the TinyThread library, as its an implemented of C++0x. Quote Programmer, Modeller Intel Core i7 930 @ 3.5GHz | GeForce 480 GTX | 6GB DDR3 RAM | Windows 7 Premium x64 Visual Studio 2008 | Photoshop CS3 | Maya 2009 Website: http://srichnet.info Link to comment Share on other sites More sharing options...
Canardia Posted October 14, 2011 Share Posted October 14, 2011 I think you mean C++0x. But you're correct. Its why I mentioned the TinyThread library, as its an implemented of C++0x. C++11, also formerly known as C++0x (pronounced "see plus plus oh ex wtf lol"). The 11 just means 2011, and the 0x means any year from 2000 to 2009. Quote ■ Ryzen 9 ■ RX 6800M ■ 16GB ■ XF8 ■ Windows 11 ■ ■ Ultra ■ LE 2.5 ■ 3DWS 5.6 ■ Reaper ■ C/C++ ■ C# ■ Fortran 2008 ■ Story ■ ■ Homepage: https://canardia.com ■ Link to comment Share on other sites More sharing options...
Scott Richmond Posted October 14, 2011 Share Posted October 14, 2011 C++11, also formerly known as C++0x (pronounced "see plus plus oh ex wtf lol"). The 11 just means 2011, and the 0x means any year from 2000 to 2009. Oh interesting. I did not know that. Quote Programmer, Modeller Intel Core i7 930 @ 3.5GHz | GeForce 480 GTX | 6GB DDR3 RAM | Windows 7 Premium x64 Visual Studio 2008 | Photoshop CS3 | Maya 2009 Website: http://srichnet.info Link to comment Share on other sites More sharing options...
Josh Posted October 15, 2011 Author Share Posted October 15, 2011 C++11 has threading facilities, so I honestly think you are wasting your time to reinvent this... Does it actually work, on OSX, Windows, Android, and iOS? Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Brent Taylor Posted October 15, 2011 Share Posted October 15, 2011 @Josh One nitpick I have is your definition for the Thread class. That was fine back in the days of C, but we have C++ now. #include "../le3.h" #ifdef WINDOWS namespace win32 { #include <windows.h> } #endif namespace le3 { enum Thread_State { THREAD_FINISHED, THREAD_RUNNING, THREAD_PAUSED, THREAD_READY }; class Thread { public: Object* result; #ifdef WINDOWS HANDLE id; Thread_State m_State; #endif Thread(); ~Thread(); virtual void Wait(); virtual bool Resume(); virtual bool Pause(); virtual int GetState(); virtual Object* GetResult(); }; Thread* CreateThread_(Object* EntryPoint(Object* o), Object* o=NULL); } An enum type is far better suited to this. Quote There are three types of people in this world. People who make things happen. People who watch things happen. People who ask, "What happened?" Let's make things happen. Link to comment Share on other sites More sharing options...
diedir Posted October 15, 2011 Share Posted October 15, 2011 time wasted C++11 and Intel Xe are ready to do this and faster.... Quote AMD Ryzen 5900HX - Nvidia RTX 3070 - 32 Go - 1To SSD - W11 Link to comment Share on other sites More sharing options...
Brent Taylor Posted October 15, 2011 Share Posted October 15, 2011 time wasted C++11 and Intel Xe are ready to do this and faster.... Keep in mind he's looking for a relatively cross platform solution. C++11, while finalized, hasn't been adopted across all compilers and runtimes yet. Intel XE is x86 specific. Neither are really appropriate. Honestly I'm going to have to agree with Metatron here. Boost::thread is the best option currently. @Josh You really should look into the Boost library. Most of it is all template code and is designed to simply be included in a project and used, not dynamically linked. It's very likely the most commonly used library used with C++ outside of the STL itself. Quote There are three types of people in this world. People who make things happen. People who watch things happen. People who ask, "What happened?" Let's make things happen. Link to comment Share on other sites More sharing options...
diedir Posted October 15, 2011 Share Posted October 15, 2011 x86 and atom compliant too Quote AMD Ryzen 5900HX - Nvidia RTX 3070 - 32 Go - 1To SSD - W11 Link to comment Share on other sites More sharing options...
Brent Taylor Posted October 15, 2011 Share Posted October 15, 2011 x86 and atom compliant too Intel's Atom processor is an x86 chip. Quote There are three types of people in this world. People who make things happen. People who watch things happen. People who ask, "What happened?" Let's make things happen. Link to comment Share on other sites More sharing options...
Josh Posted October 17, 2011 Author Share Posted October 17, 2011 With Windows threads at least, they are supposed to use this type of entry point: DWORD WINAPI EntryPoint( LPVOID lpParam ) I see 32 bits in and 32 bits out, so is it okay to replace it with this?: (LPTHREAD_START_ROUTINE)(Object* EntryPoint(Object* o)) Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Josh Posted January 15, 2012 Author Share Posted January 15, 2012 I added a C++ tag to this thread by editing the first post in the full editor, then moved it to the general programming forum. I don't recommend going through and tagging every single post, but I just wanted to make sure it worked. Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Clackdor Posted January 15, 2012 Share Posted January 15, 2012 Useful thread is useful. I have a better understanding of enum now. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.