class A
{
public:
void EntryPoint();
private:
void DoTask(Task* task);
};
void A::Entrypoint()
{
Task* t;
//Assign something to t
pthread_create(ID, NULL, &A::DoTask, t);
}
void A::DoTask(Task* task)
{
//Do stuff
}
Obviously, the '&A::DoTask' parameter wont work and I'm really not sure of how to run DoTask from the thread creation. All of the tutorials I've looked at so far are for functions that dont take any parameters.
I didn't put this thread in the unix catagory because I plan on extending this program to windows, and I'm pretty sure that windows's CreateThread takes the same sort of thing as pthread_create.
Hmm,
Boost does seem like an easier option, but I feel like including a lib like boost instead of just figuring out how to reference my threads starting points is a little silly (i also dont have much experience with using libs).
Will it be much more difficult to do it without boost?
Thanks for your help so far though kbw
This is a thread base class that you derive from. How does it work? start() creates the thread using the local static ThreadFunc(). ThreadFunc() then calls the derived class' run().
1 2 3 4 5 6 7 8 9 10 11 12 13
class Counter : public Thread
{
size_t _mx;
std::string _prefix;
void run()
{
for (size_t i = 0; i != _mx; ++i)
std::cout << _prefix.c_str() << i << std::endl;
}
public:
Counter(size_t mx, constchar* prefix) : _mx(mx), _prefix(prefix) {}
};
You use it like this.
1 2 3 4 5 6
int main()
{
Counter c1(10, 'A');
c1.start();
WaitForSingleObject(c1.handle(), INFINITE);
}
kbw, That looks great! (from what I can understand)
Can you please give me a quick explanation of what each line in your example usage does? I'm having a little trouble understanding.
main.
Line 3: Instantiate Counter object.
Line 4: Start its thread
Line 5: Wait for it to complete.
I missed the return 0, but I just wrote this in the forum without compiling it.
Counter:
Line 1: Inherit from Thread so we can do thread things.
Line 3, 4: Declare class members.
Line 6: run() is the thread function. We just write some text to cout without synching with anything.
Line 12: Constructor initialised classes members.
Thread:
Line 1: Declare the thread class.
Line 3: _handle is the thread handle used by the OS.
Line 4: ThreadFunc is the static function passed to the thread create function.
Line 5: Declare run() as pure virtual. This is the concurrent function that derived classes override.
Line 6: start() starts the thread running.
Line 8: Virtual destructor because we're a base class.
I forgot the constructor and copy stuff, but like I said, the code was never compiled.
Line 11: start() calls the stuff to create and start a thread using ThreadFunc passing in this as the parameter.
Line 19: ThreadFunc is passed the object that is to be run, so it calls run() on that object. It checks for null.
I hope this helps. I don't know how to be more explicit.
Ok.. Can you please explain what mx is if it's not just an example?
Also, how is threadfunc specified? Does that need to be set between the counter initialisation and c1.start();?
_mx and _prefix are just member variables that the thread uses. It's no big deal, you can put anything in your thread class.
The WIN32 thread handle is HANDLE.
The pthread handle is pthread_t.
If you're even contemplating portability, use boost threads. There's more to threading than a thread class. You also have to sync occasionally. If you're from a Windows background and used to using events, spend a bit of extra time trying to understand conditions before you begin.
So I can just include some headers from boost.. Will this create any dependancies for the end user? I remember using boost in the past and having to have boost libs installed, but if im using headers that wont happen?
If you are using header-only libraries, it won't create any dependencies for the end user. I believe the thread library is a library however. You can statically link it, which would increase the size of your executable but it would prevent the user from needing to acquire the library.
Ok, I overlooked the noobest mistake of them all.
My routine that created all of these threads was exiting before the threads themselves.
All is well now and I thank everyone again for their help.