Jump to content
  • Advertisement
Sign in to follow this  
swiftcoder

Multi-threading question

This topic is 4230 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have an idea for a system, but I am not sure of the best/feasable ways to implement it. I haven't made much headway in reading web-based threading resources, and wondered if any of you could give me a few pointers... Basically, I want to run 3-4 threads concurrently, each performing a different part of the same task (there are no shared resources to worry about). So, I want to start all 3 threads, which each perform certain tasks each frame. The frame is done when all 3 finish running, and then the 1st thread will perform bookkeeping, etc., after which it will start the next frame by resuming each of the threads. So basically, I need to spawn 2 additional threads, wait until all 3 threads are done, and then start them again after bookkeeping in the initial thread. I realise that may not be the clearest explanation, so tell me if it needs clarification. It looks to me as if this could be done with either conditional variables, or with a semaphore. Am I correct in this, and would one have huge benefits over the other? Also, while the implementation using semaphores seems straight forward, I am still not clear how this would be done using conditional variables?

Share this post


Link to post
Share on other sites
Advertisement
Don't start and stop your threads. That's an expensive operation you want to avoid. Create all your threads at the beginning, then have them wait on a condition variable for the signal to process something.

If you need to wait for more than one thread, you're better off using a semaphore. You can implement a semaphore using a mutex or a condition variable (which also can be implemented using a mutex) if your toolkit does not supply one. Think of a condition variable as a semaphore with the range [0, 1].

--smw

Share this post


Link to post
Share on other sites
Quote:
Original post by Bregma
Don't start and stop your threads. That's an expensive operation you want to avoid.

Sorry, lack of terminology here, I didn't literally mean to stop and start....

Quote:
If you need to wait for more than one thread, you're better off using a semaphore. You can implement a semaphore using a mutex or a condition variable (which also can be implemented using a mutex) if your toolkit does not supply one. Think of a condition variable as a semaphore with the range [0, 1].

--smw


I have semaphores, so no problem there. Basically, if I understand it correctly, as each of my 3 threads finishes, it waits on the semaphore, and when the main thread is ready to run the next frame, it signals the semaphore 3 times, to let the threads run again? Now how would I implement it if the controlling thread is in fact one of these 3 threads (and I of course have no way of telling which will take the least time)?

It seems that the main thread would signal the semaphore twice, which would allow the other 2 threads to run, and then the frame is over when the semaphore count once again reaches 2 waiting threads and the main thread is finished processing. Is this in fact logical/workable?

Share this post


Link to post
Share on other sites
Quote:
Original post by swiftcoder

I have semaphores, so no problem there. Basically, if I understand it correctly, as each of my 3 threads finishes, it waits on the semaphore, and when the main thread is ready to run the next frame, it signals the semaphore 3 times, to let the threads run again? Now how would I implement it if the controlling thread is in fact one of these 3 threads (and I of course have no way of telling which will take the least time)?

It seems that the main thread would signal the semaphore twice, which would allow the other 2 threads to run, and then the frame is over when the semaphore count once again reaches 2 waiting threads and the main thread is finished processing. Is this in fact logical/workable?


Each thread looks like this;

while (alive) {
// one mutex per thread
mutex.wait();
pending++;
// do work
pending--;
main_mutex.notify()
]


Then you have your main thread. Once it needs to offload the work:

pending = 0;

thread1.setData();
thread1.mutex.notify();
thread2.setData();
thread2.mutex.notify();
thread3.setData();
thread3.mutex.notify();

while (pending > 0) {
main_mutex.wait();
}


This is somewhat crude, but it illustrates the basic concept.

The mutex.wait() will simply block until someone calls .notify() on it.

Note that depending on your implementation you obviously need to make sure that pending and other variables, as well as locks work in such a way that some thread doesn't get stuck.

Share this post


Link to post
Share on other sites
A mutex doesn't do wait and notify. That's a condition variable.

Your main thread should be waiting on a semaphore that gets incremented or decremented by the worker threads. The worker threads wait on a condition variable that gets signalled by the main thread. The main thread uses a wake-all signal to wake the worker threads.

--smw

Share this post


Link to post
Share on other sites
Quote:
Original post by Bregma
A mutex doesn't do wait and notify. That's a condition variable.

Your main thread should be waiting on a semaphore that gets incremented or decremented by the worker threads. The worker threads wait on a condition variable that gets signalled by the main thread. The main thread uses a wake-all signal to wake the worker threads.

--smw


So when each worker thread is done, it signals the semaphore, and waits on the conditional variable. when the main thread is done, it waits on the semaphore, and then after doing housekeeping, broadcasts the conditional variable to resume the worker threads?

[Edited by - swiftcoder on March 25, 2007 2:06:29 PM]

Share this post


Link to post
Share on other sites
This could be the same thing as a semaphore...

I have the exact setup working with a couple threads per core. Each thread has 2 win32 events (created with CreateEvent), a "start" event and an "end" event. The main thread sets the start event and waits for the end event. Each thread waits for the start event, processes, and sets the end event.

Hope that helps.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!