Thread: Block and wake up certain threads

  1. #1
    Registered User
    Join Date
    May 2002
    Posts
    41

    Question Block and wake up certain threads

    This is my next challenge.
    I have several threads waiting there. Another thread is polling a database and when it finds something, it puts something in a datastructure that is owned by a thread (every thread owns one of those structures). Currently all those threads do a constant loop with a usleep of 200 ms. Without a sleep this would take too much CPU power. This isn't fast enough for me though, I want that the threads are each locked and awaken as soon as the polling threads has no data for them.
    I did this with a condition variable and it kinda works but I think it's wrong. I just have every thread blocking at a condition variable, then when the polling thread has new data it sends a pthred_cond_broadcast to awaken all threads. This works but I don't think it's "good". When I understand condition variables correctly, that's not how they are supposed to be used.
    What I want to do is, that the polling thread can signal certain threads to awake (yes I will store the ID's of each thread of course). So whenever it has finished putting the data into a threads buffer it should signal it something like "check your buffer". The thread then reads this buffer, works with it and blocks again waiting for the next call.
    Any ideas how this could be done?

  2. #2
    ....
    Join Date
    Aug 2001
    Location
    Groningen (NL)
    Posts
    2,380
    You could implement a messaging system. Define a list of messages and declare a variable in which messages are stored. If a reading thread has put data in for example buffer 1, then it could put the message BUFFER_1_FILLED in the variable. The other threads are constantly checking for messages in those variable. If a message is send on which they have to take action, then they will process the message. If a lot of messages are generated, then you would need a message buffer.

    I understand that every thread owns one of the datastructures, so for each datastructure you could define a message. The threads know which message they need to look for. If the message which tells that they have to take action is send, then they will do the action as required. Also the message buffer needs to be updated, messages need to be deleted if they are processed.

  3. #3
    Registered User
    Join Date
    May 2002
    Posts
    41
    Yep, that's somehow what I thought. My big problem though is, that I have no idea how to wait for those messages to arrive (I'm still a bloody newb in most areas ).
    So what do you mean with message variable, a simple int? That should work but how do I wait for a message?
    The only way I know is a construct like
    while (!message)
    but those endless while loops tend to eat up all my CPU ressources. When I wait with - for example - pthread_cond_wait() than they eat no CPU ressources but I don't know how this is done.
    So basically I just need a way to do something like this:
    "Wait until message is set without doing anything"

  4. #4
    Registered User
    Join Date
    May 2002
    Posts
    41
    I searched (almost) the whole web for it and still couldn't find any information on how to do a passive wait... It has to be possible somehow, especially with threads. Please help me if you have any idea...
    I just want something like sleep_until(condition == 1).
    With condition variables I can actually do the sleep but I can either wake up ALL threads waiting on this var at once. But I want to control exactly which thread to wake up so this doesn't work. Wait, I could try to put a mutex and a condition var into every structure that is owned by a thread... Maybe I can then use those to wake up a certain thread... I will try this, please tell me if the idea is stupid so I don't waste time on it when I read it early enough.

    EDIT: It works!
    Not sure if this is the best idea but it seems to work flawlessly.
    Last edited by Spark; 05-31-2002 at 08:35 AM.

  5. #5
    Registered User
    Join Date
    May 2002
    Posts
    1
    If you are programming for Windows, you could use the WaitForSingleObject or WaitForMultipleObjects api's.

    This is something like sleep_until(condition=1).

  6. #6
    Registered User
    Join Date
    May 2002
    Posts
    41
    Hmm no, it's Linux.

  7. #7
    ....
    Join Date
    Aug 2001
    Location
    Groningen (NL)
    Posts
    2,380
    What I meant with the message system was something like this:

    Code:
    Process_A ()
    {
        while (1)
        {
            wake_up = false;
        
            while (wake_up == false)
            {
                /* Check message buffer */
                switch (message)
                {
                    case WAKE_PROCESS_A:
                        /* Wake up process A only */
                        wake_up = true;
                        break;
                    case WAKE_ALL_PROCESSS:
                        /* Wake up all processes */
                        wake_up = true;
                    case ....
                        /* Some other messages on which
                           the process should wake up */
                    default:
                        break;
                }
            }
            
            /* Now the process has waken up and must do
               the things it needs to do. */
               
            ...
            
            /* Everything that need to be done is done,
               the process can sleep again. */
            wake_up = false;       
        }
    }
    There are some other methods, but I see that your method works. It looks OK, although personally I would split control and data. So I would have some global array in which the condition variables are stored. The threads only check their condition variable and wake up if necessary.

  8. #8
    ....
    Join Date
    Aug 2001
    Location
    Groningen (NL)
    Posts
    2,380
    A good site with lots of info:

    http://www.cs.cf.ac.uk/Dave/C/

  9. #9
    Registered User
    Join Date
    May 2002
    Posts
    41
    But wouldn't take up such a while(message == FALSE) loop eat up all CPU resources? That would be the easiest way to do it otherwise... The method with condition vars works very good though. I'm just a little bit worried that it might be overhead and overhead is really something I don't need for a chat that is supposed to serve hundreds of chatters eventually.

  10. #10
    Registered User
    Join Date
    May 2002
    Posts
    41
    *bump*
    Still looking for a better solution. I'm worried that maintaining 600 condition vars might be overkill especially because settings all those signals is extremely time critical. Please, someone has to know how to do a "soft wait" like a while() loop without using system resources.

Popular pages Recent additions subscribe to a feed