CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Nov 2011
    Posts
    4

    what happens if the main thread in not waiting for the signal and it receives one?

    Hi
    I need clarification regarding a code segment which in brief waitsfor a signal, but can receive signals from multiple threads. Just to clarify my stmt here is the code segment (outline)

    process()
    {
    .... pthread_cond_wait.... //--> waiting for the signal
    /*remaining part of code*/
    }

    callback_func1()
    {
    ...pthread_cond_signal.. //--> assume thread1 calls this function and it signals the waiting thread
    }

    callback_func2()
    {
    ...pthread_cond_signal.. //-->assume thread2 calls this function and it also signals thewaiting thread
    }

    I understand that callback functions gets executed under their respective calling thread scope i.e. callback_func1() when called will get executed as part of Thread1.
    When Thread1 calls callback_func1() and it signals the condition, the main thread is awakened and continues to execute /*remaining part of code*/ in process() func.
    At this point if Thread2 calls callback_func2() and it also signals the condition.
    I am not very clear what happens now, Please clarify me in this scenario.
    1. Since the main thread is already awakened and is not in wait state I am under the assumption that the signal by Thread2 after calling callback_func2() will be missed permanently.
    2. How should I solve this problems, i.e. both the threads should have their signals processed. None of thread after sending the signal should miss out to execute the /*remaining part of code*/

  2. #2
    Join Date
    Nov 2003
    Posts
    1,902

    Re: what happens if the main thread in not waiting for the signal and it receives one

    Condition variables should always be used with a "predicate loop":
    Code:
    pthread_mutex_lock(&Lock);
    while (<predicate condition>)
        pthread_cond_wait(&Cond, &Lock);
    // condition signaled work
    pthread_mutex_unlock(&Lock);
    
    ...
    
    pthread_mutex_lock(&Lock);
    <update predicate state>
    pthread_cond_signal(&Cond);
    pthread_mutex_unlock(&Lock);
    So in this case the "predicate state" could be "number of threads that have signaled".
    The "predicate loop" would then be "while the number of threads that have signaled is 0, wait".
    Code:
    int num_signaled = 0;
    ...
    pthread_mutex_lock(&Lock);
    while (num_signaled == 0)
        pthread_cond_wait(&Cond, &Lock);
    num_sigs_this_pass = num_signaled;
    num_signaled = 0;
    pthread_mutex_unlock(&Lock);
    // process num_sigs_this_pass
    
    ...
    
    pthread_mutex_lock(&Lock);
    num_signaled += 1;
    pthread_cond_signal(&Cond);
    pthread_mutex_unlock(&Lock);
    gg

  3. #3
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: what happens if the main thread in not waiting for the signal and it receives one

    That's over-complicating it slightly. He wants to wait for both threads to signal, and it shouldn't matter if they signal before or while the main thread is waiting, or in which order they signal.

    Code:
    int num_signaled = 0;
    ...
    spawn thread 1
    spawn thread 2 // must do these after initializing num_signaled to 0
    ...
    pthread_mutex_lock(&Lock);
    while (num_signaled != 2)
        pthread_cond_wait(&Cond, &Lock);
    pthread_mutex_unlock(&Lock);
    
    ...
    
    // worker threads 1 and 2 can share this code
    pthread_mutex_lock(&Lock);
    num_signaled += 1;
    pthread_cond_signal(&Cond);
    pthread_mutex_unlock(&Lock);

  4. #4
    Join Date
    Nov 2003
    Posts
    1,902

    Re: what happens if the main thread in not waiting for the signal and it receives one

    >> He wants to wait for both threads to signal ...
    That's not what I parsed out from "2." in the first post.

    Quote Originally Posted by Lindley View Post
    Code:
    ...
    pthread_mutex_lock(&Lock);
    while (num_signaled != 2)
        pthread_cond_wait(&Cond, &Lock);
    pthread_mutex_unlock(&Lock);
    ...
    That doesn't solve your interpretation of the problem. What if thread 1 signals twice (thread 2 hasn't signaled yet)? What if num_signaled becomes greater than 2?

    If we have a thread 1 and thread 2, and both threads need to "signal" a 3rd thread to run - then using a barrier would be the easiest approach.

    If we just need to make sure that "/*remaining part of code*/" is run for every callback_func1() and callback_func2() call - then the pseudo-code in post #2 shows one way to do that.

    gg

  5. #5
    Join Date
    Nov 2011
    Posts
    4

    Re: what happens if the main thread in not waiting for the signal and it receives one

    Hi, Interpretation of "gg" reg point 2 is what I need.
    The code outline which I mentioned is of the application, The app calls a library function which is inturn responsible for spawning the threads, the no. of threads spawned is dynamic. Suppose for e.g. initializtion and events represent the 2 callbacks. So each thread calls the callback functions accordingly when there are initialized (callback_func1() ) or they receive events(callback_func2() ). The number of times and the order in which callback_func1() and callback_func2() is called is unpredictable. Also on the app side I am not suppossed to maintain which threads "init" or "event" is being received.

    "gg", can you please elaborate on your post#2 example, I am new to multithreading and mutex condition variables. Could not get the purpose of "num_sigs_this_pass"

  6. #6
    Join Date
    Nov 2003
    Posts
    1,902

    Re: what happens if the main thread in not waiting for the signal and it receives one

    >> please elaborate on your post#2 example
    Code:
    int num_signaled = 0;
    pthread_cond_t Cond = PTHREAD_COND_INITIALIZER;
    pthread_mutex_t Lock = PTHREAD_MUTEX_INITIALIZER;
    
    void process()
    {
        ...
        pthread_mutex_lock(&Lock);
            while (num_signaled == 0)
                pthread_cond_wait(&Cond, &Lock); // this releases Lock while waiting
           
            int num_sigs_this_pass = num_signaled;
            num_signaled = 0;
        pthread_mutex_unlock(&Lock);
        
        // we have been signaled 'num_sigs_this_pass' times
        for (int n = 0; n < num_sigs_this_pass; ++n)
            /*remaining part of code*/
        ...
        // loop back to top and do it again
    }
    
    void signal_process()
    {
        pthread_mutex_lock(&Lock);
        num_signaled += 1;
        pthread_cond_signal(&Cond);
        pthread_mutex_unlock(&Lock);
    }
    
    void callback_func1() {signal_process();}
    void callback_func2() {signal_process();}
    >> Could not get the purpose of "num_sigs_this_pass"
    The "num_signaled" variable can only be accessed while "Lock" is acquired. While "Lock" is acquired, "num_signaled" is saved off and reset back to 0. Then once "Lock" is released, the code processes the "num_sigs_this_pass" number of signals.

    Without "num_sigs_this_pass", the code would have to process "/*remaining part of code*/" with "Lock" acquired - which is unnecessary. "Lock" should only be used with "Cond", and to protect "num_signaled". In general, the duration that a lock remains acquired should be minimized.

    gg

  7. #7
    Join Date
    Dec 2011
    Posts
    3

    Re: what happens if the main thread in not waiting for the signal and it receives one

    Hello every one, if any one find any flaws in my solution please point me out

    i guess you want proceed further only when you got a signal from both the thread, and both thread are executing diffrent functions

    pthread_t thread1;
    pthread_t thread2;

    int var_thread1 = 0;

    int var_thread2 = 0;


    process()
    {

    pthread_mutex_lock(&lock);
    while(var_thread1 * var_thread2 = 1)
    pthread_cond_wait(&cond,&lock);
    ...................
    ...................
    pthread_mutex_unlock(&lock);

    }


    thread1_Fun()
    {
    var_thread1 = 1;
    pthread_cond_signal(&cond);
    }

    thread2_Fun()
    {
    var_thread2 = 1;
    pthread_cond_signal(&cond);
    }

  8. #8
    Join Date
    Nov 2003
    Posts
    1,902

    Re: what happens if the main thread in not waiting for the signal and it receives one

    >> any flaws in my solution please point me out
    The while loop in process() is wrong.
    You need to lock/unlock in thread1_Fun() and thread2_Fun().

    With that fixed, the code will block process() until thread1_Fun() and thread2_Fun() have been called at least once, then it never blocks on the condition again.

    If var_thread1 and var_thread2 were reset back to 0 before process() unlocks, that wouldn't be very useful either. What if thread1_Fun() is called N times and thread2_Fun() is called once? How many times should process() be "signaled" in that case: 1 or N+1 times? If the answer is 1, then a barrier is the best tool for the job. If the answer N+1 then the code in post #6 can handle that.

    gg

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured