Advertisement

Multi-thread question

Started by May 12, 2017 01:02 AM
7 comments, last by DividedByZero 7 years, 6 months ago

Hi Guys,

I am trying to get my head around multi-thread (solely for learning purposes at this stage).

I have created a basic networking class which is connecting fine at the moment able to connect to multiple clients etc. No problems.

I want to be able to connect to multiple clients at the same time using multi-threading (again, for learning purposes).

I have two classes Network and Connection.

'Network' has a vector of 'Connection'. So each client we want to (attempt) to connect to gets pushed on to that vector.

Network.ConnectAll() then iterates through each 'Connection' in the list to try to connect to it.

I am trying to work out a way to multi-thread this part of it so each connection attempt happens in its own thread.

So far I have the following;


int ConnectAllThreaded()
{
     for (std::vector<Connection>::iterator it = connectionVector.begin(); it != connectionVector.end(); ++it)
     {
          std::thread t1(&it->Connect);
          t1.join();
     }
     return 0;
}

Obviously this is a bit flawed as each thread will be waiting to join() so I need to look into how to get around that. But at this stage it wont even compile.

'&': illegal operation on bound member function expression
Any help and guidance with how I can make this work would be greatly appreciated.
Thanks in advance :)
Member functions and free functions don't work the same way in C++ - member functions have an implicit "this" argument that has to be bound to something. Taking the address of a bound member function isn't meaningful. If you want the address of the member function, then you probably want Connection::Connect. Useful reading.

On top of that, I don't believe you need to pass a function pointer into std::thread - the function argument to std::thread is actually a template parameter that should resolve to something that can be called. Subsequent arguments to the std::thread constructor are the arguments to be passed to the callable thing. Bearing in mind that I haven't actually tried this:
std::thread t1(Connection::Connect, &*it);
Here is the relevant documentation for std::thread, which may prove useful.
Advertisement

Hi Oberon,

Thanks for the reply.

I just tried your code snippet and it give me this error;


'Connection::Connect': non-standard syntax; use '&' to create a pointer to member

Having a look at the link you provided right now. Thanks again, so far :)

Try to use the first parameter in the first answer of this thread.


http://stackoverflow.com/questions/10673585/start-thread-with-member-function
Just changed your suggestion slightly and it worked :)

std::thread t1(&Connection::Connect, &*it);
The other half of the issue is the t1.join() call. How can I keep this in scope to allow all connections to be called simultaneously?

for (std::vector<Connection>::iterator it = connectionVector.begin(); it != connectionVector.end(); ++it)
{
    std::thread t1(&Connection::Connect, &*it);
    // t1.join();
}
 
for (std::vector<Connection>::iterator it = connectionVector.begin(); it != connectionVector.end(); ++it)
{
    t1.join();   // Obviously out of scope
}
In other words. Start the threads and then come back an rejoin all of them later.
Also, joining right after the starting the thread is not a good idea, since you will only be able to have one or two threads running at a time. In order to use the full potential of multi threading, you should try to parallelize you work. By splitting your work into two loops, one loop to boot the threads, and another to join them, it will allow your threads to keep booting one right after the other and work all at the same time until they complete their task.

Also, threads are a pretty low level and can easily be misused. C++ 11 I believe added a stl class called "future" which wrap threads and make them easier to use.

EDIT:
Typed at the same time.as you :p. Try keeping a vector of threads, so that you can call join on them later.
Advertisement
Zilmerx I think I ninja'd you with the next part of my question. Any ideas how I can get around this problem?

[edit] We seem to be editing around each other - LOL.

I'll have a look at your vector of threads suggestion and see what I can come up with. Thanks again for your help so far :)
Try keeping a vector of threads, so that you can call join on them later.
I managed to get the thread vector working, by doing this;


	void ConnectAllThreaded()
	{
		for (std::vector<Connection>::iterator it = connectionVector.begin(); it != connectionVector.end(); ++it)
		{
			threadVector.push_back(std::thread(&Connection::Connect, &*it));
		}
		
		for (std::vector<std::thread>::iterator it = threadVector.begin(); it != threadVector.end(); ++it)
		{
			it->join();
		}
	}
Seems to work perfectly!

A huge thanks for your help, guys! :)

This topic is closed to new replies.

Advertisement