Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Multithreading and events

This thread is locked; no one can reply to it. rss feed Print
Multithreading and events
Gnamra
Member #12,503
January 2011
avatar

I'm really new to multithreading, I've looked at the tutorial in the wiki. And I've got a few questions.

1. a mutex is used so only one thread can read / write on whatever is between

al_lock_mutex(mutex)

stuff

al_unlock_mutex(mutex)

And it's only used when reading / writing shared resources like the data class in the example, right?

2. What I want to do is have a thread which handles all input, but I can't get it to work. I tried adding an ALLEGRO_EVENT ev, to the data class. and copy the ALLEGRO_EVENT in the main loop to the ALLEGRO_EVENT in the data class. like this:

al_wait_for_event(event_queue, &ev);

al_lock_mutex(data.mutex);
data.ev = ev;
al_unlock_mutex(data.mutex);

Is there anything wrong with this?

3. In the input_thread function I've got:

while(!al_get_thread_should_stop(thr)){
  al_lock_mutex(data->mutex);
        blah blah 
        al_unlock_mutex(data->mutex);
}

When the mutex is locked in the main loop, and I'm copying the ev to the data.ev, is the thread waiting for the mutex to be unlocked in the main before continuing with "blah blah".

J-Gamer
Member #12,491
January 2011
avatar

1. You can use mutexes to tell other threads to not touch the data protected by the mutex.

2. If you want to send events to another thread, the other thread should have an event queue listening to that kind of events.

3. If you want to lock a mutex that is already locked, the thread will wait until it's unlocked.

EDIT: here's a good read on multithreading: http://msdn.microsoft.com/en-us/magazine/cc163744.aspx (I know it uses .NET, but the same principles apply in every multithreaded environment)

" There are plenty of wonderful ideas in The Bible, but God isn't one of them." - Derezo
"If your body was a business, thought would be like micro-management and emotions would be like macro-management. If you primarily live your life with emotions, then you are prone to error on the details. If you over-think things all the time you tend to lose scope of priorities." - Mark Oates

Elias
Member #358
May 2000

Which tutorial are you referring to?

In general, something like your code under 3. makes no sense. Using a mutex means you force the code inside to be single threaded again. So if you lock your whole loop body - why are you using an extra thread in the first place? Threads are for when you want to run things in parallel.

--
"Either help out or stop whining" - Evert

Gnamra
Member #12,503
January 2011
avatar

Oh, thanks for the help! I'll try adding an event_queue to the data class.

Also, this is the tutorial I was referring to: http://wiki.allegro.cc/index.php?title=Allegro_5_Tutorial/Threads

in there he locked the entire loop as well:

   while(!al_get_thread_should_stop(thr)){
 
      al_lock_mutex(data->mutex);
      if(modi_X)
         data->posiX += num;
      else
         data->posiY += num;
      al_unlock_mutex(data->mutex);
 
      al_rest(0.01);
 
   }

and it makes sense to me, because if you don't lock it while messing with the data->posiX, then any other thread could mess with it while the first thread is? And since I'm using events, I don't want the event to change in the middle of checking what event type it is. Perhaps I'm just really misunderstanding the whole thing.

Edit: Oh, I'm not sending them. I'm just copying the info in one over to the other in the data class.

J-Gamer
Member #12,491
January 2011
avatar

If a thread wants to listen to events, it has to have its own event queue, on which the events you want it to listen to are registered.

The example locks the mutex on the whole thread because the only thing that thread does is change things from the shared data. In general, you only want mutexes around the parts where you access the shared data. If that's the only thing you do, you should probably don't do it in a separate thread. Where threads come in most handy is with AI for example. It makes a bunch of calculations and then puts it results in the shared data for the main game to pick up. It will only have mutexes around the parts where it reads/writes data to the shared memory, not where it does its AI logic.

" There are plenty of wonderful ideas in The Bible, but God isn't one of them." - Derezo
"If your body was a business, thought would be like micro-management and emotions would be like macro-management. If you primarily live your life with emotions, then you are prone to error on the details. If you over-think things all the time you tend to lose scope of priorities." - Mark Oates

Gnamra
Member #12,503
January 2011
avatar

I see, and again thanks for the help :D I got it working, and a much better understanding of how it all works. I'm going to do some more experimentation. Also that article was very useful.

Edit: I've read through about half of the article and experimented a bit, and I'm wondering what would happen if:

i is a global variable.

thread 1:
i = 25;
al_lock_mutex(m)
i = 50;
al_unlock_mutex(m);

thread 2:
std::cout << i << std::endl;

now assuming thread 2 is trying access the memory location of i while mutex has locked that memory location. I'm guessing it either gives an error or exception.

Go to: