Skip to main content
gamedev.net
🔒 Locked

Thread safe streaming objects into world

Started by Lloydg Jun 29, 2010 at 11:41 PM 3 replies 1.1k views
Original Post
Lloydg
Lloydg
What i want to do is stream objects from a server into the world.

What i was thinking was doing something like this.

thread one is the Game's Main Loop:

thread two is the Streaming thread:

And how they interact is with a queue.

For the queue i was thinking of a std::vector queue;

So for the streaming thread, after it makes a new Object it would push it onto the queue. ( queue.push_back(newObject); )

And then in the thread one at the beginning of each frame it would do something like:
for (int i = 0; i < queue.size(); i++)
{
world->addObject(queue.at(i));
queue.erase(queue.begin()+i);
}

My question is: is this all thread safe? is this a good way of doing it? if not what is a good way?

Thanks heaps, Lloyd
Hodgman
Hodgman
Yeah that's a good idea - it's a kind of "message passing" between the threads.

It's not thread safe as you've written it. It is thread safe if you implement mutual exclusion - you've got to ensure that only one thread is touching the std::vector at a time. You can do this via Mutexes/Critical-sections. You lock the mutex/critical-section before doing anything that involves the vector, and then you unlock it afterwards.

Also, if 'addObject' does any processing (i.e. it's not really quick), you should do it while the mutex is unlocked, so that the other thread can access the vector during the call to 'addObject'. e.g.
while( true ){  lock mutex  if( queue.empty() )    empty = true;  else    empty = false;    item = queue.back()    queue.resize( queue.size()-1 )  unlock mutex  if( empty )    break;  world->addObject( item );}
Ohforf sake
Ohforf sake
I think it wouldn't even run without multithreading. The queue.erase would screw up your index calculation. It might be a better choice to let the queue intact within the for loop and clear the whole thing afterwards.
I would also prefer pointers inside the vector, as it keeps down the overhead of copying things around.

Now about multithreading, no it is not safe. You need to guard the queue with a mutex. However, just throwing in mutexes easily slows down performance. If "latency" is not a problem, a double buffered queue might be a better choice. You create two queues, the streaming thread writes to the "front" queue, the game thread reads from the "back" queue and when the game thread is finished it will lock a mutex and switch both queues.
Lloydg
Lloydg
Ok, thank you both. Sorry it was meant to be a vector.

Ok i had another thort, i am using SDL and it has a event system. could i post a message saying added this pointer to an object into the world? would the be smarter?

or should i stick the the queue[s] way with mutex locking?.

And SDL has the mutex stuff as part of its library? because i need something cross platform.

Thanks.
scope
scope
If you have one producer, one consumer thread, why not use a lockless queue?

http://mooproductions.blogspot.com/2006/12/lockless-queue-revision.html


Also, my choice for a stl queue would be a std::queue.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.