Thread: Message box as thread to stop main thread

  1. #1
    Registered User
    Join Date
    Sep 2003
    Posts
    224

    Message box as thread to stop main thread

    Hello,

    My main thread does some computation indefinetly. To stop the computation, I created a thread that displays a message box, and when pressed, sets a global variable that stops the main program loop. However, my program just hangs when I get the start the thread. The message box does not show up either. Here's the code:

    Code:
    static bool keep_sending;
    
    static UINT thread_func(LPVOID pParam)
    {
      AfxMessageBox("Please OK to stop");
      keep_sending = false
      
      return 0;
    }
    
    void A::func(void)
    {
      CWinThread *pthread;
    
      keep_sending = false;
    
      if(some_condition)
      {
        keep_sending = true;
        pthread = AfxBeginThread(thread_func, NULL, THREAD_PRIORITY_NORMAL);
      }
      
      do
      {
        // do some stuff
      }while(keep_sending);
    }
    Thanks.

  2. #2
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    AfxMessageBox needs the main GUI thread to be pumping messages. You should reverse your scheme. Launch a worker thread to do the computations and run the message box in the main thread.

  3. #3
    Registered User
    Join Date
    Aug 2002
    Location
    Hermosa Beach, CA
    Posts
    446
    maybe also declare your global bool to be volatile, this may be your problem.
    The crows maintain that a single crow could destroy the heavens. Doubtless this is so. But it proves nothing against the heavens, for the heavens signify simply: the impossibility of crows.

  4. #4
    Registered User
    Join Date
    Sep 2003
    Posts
    224
    Quote Originally Posted by anonytmouse
    AfxMessageBox needs the main GUI thread to be pumping messages. You should reverse your scheme. Launch a worker thread to do the computations and run the message box in the main thread.
    I tried doing that, but since the function has to be a non member function, I can't access any of the class members. I'll make the function friend function and see if that'll help.
    maybe also declare your global bool to be volatile, this may be your problem.
    How would turning off the caching help?

  5. #5
    Registered User
    Join Date
    Aug 2002
    Location
    Hermosa Beach, CA
    Posts
    446
    My understanding is that is what volatile is for, by definition. You are checking the value of keep_sending in one thread, and updating it in another. The problem might be that the thread in the while loop doesn't realize the value has changed, precisely because the value changed in a different thread. Anyway, it's really easy to try, so why not test the theory?
    The crows maintain that a single crow could destroy the heavens. Doubtless this is so. But it proves nothing against the heavens, for the heavens signify simply: the impossibility of crows.

  6. #6
    Registered User
    Join Date
    Aug 2003
    Posts
    470
    My understanding is that is what volatile is for, by definition. You are checking the value of keep_sending in one thread, and updating it in another. The problem might be that the thread in the while loop doesn't realize the value has changed, precisely because the value changed in a different thread. Anyway, it's really easy to try, so why not test the theory?
    if the variable is cached in a register, then one thread could write to the register(but not the same variable in static memory), context switch, and then the other thread could read from the variable. But instead of reading the new value, the other thread would read the old value. .

    Yasir_Malik, your gui thread must spawn a thread and then show the message box. (You'd want to avoid the situation of spawning the thread, have the thread exit, and then show the message box.) Then the worker thread continues processing, but when the user pressses a button on the message box, the static variable is set. This occurs in the gui thread. (The gui thread will probably either poll or wait for the worker thread to exit. ) Then, the worker thread eventually read the variable and knows to exit.

  7. #7
    Registered User
    Join Date
    Sep 2003
    Posts
    224
    Thanks. If by "gui thread" you mean the main thread, that's exactly what I did. The gotcha was that the thread function has to be a global function or static function member function, which in either case does not allow access to the member variables. A work around at http://www.codeproject.com/threads/memberthread.asp fixed that.
    I don't think making keep_sending volatile would make a difference (even though I added it anyway) in my code because the worker thread is not changing keep_sending. Instead, it's just reading the value that the main thread sets after the message box is clicked.
    Last edited by Yasir_Malik; 04-10-2006 at 09:03 AM.

  8. #8
    Registered User
    Join Date
    Aug 2003
    Posts
    470
    I don't think making keep_sending volatile would make a difference (even though I added it anyway) in my code because the worker thread is not changing keep_sending. Instead, it's just reading the value that the main thread sets after the message box is clicked.
    The worker thread might be reading a register that is caching the value stored statically. Say, for instance, I wrote
    Code:
    static int staticVar = 1;
    
    void f()
    {
           while(staticVar <= 100)
                  staticVar++;
    }
    This isn't how the code looks compiled. I doubt a good compiler would access memory more than twice, but instead do something like

    Code:
    static int staticVar = 1;
    
    void f()
    {
           reg = staticVar;
    
           while(reg <= 100)
                  reg++;
    
           staticVar = reg;
    }
    reg representing any register, This then runs faster as the time to access a register is faster than to access memory. But say while function f is executing staticVar changes, due to a another thread accessing staticVar, then function f has no way of knowing it's supposed to change reg. Without volatile you could run into a situation where the main thread sets keep_sending to false but the worker never reads from the variable in memory, but only in the register, resulting in the worker thread never stopping.

  9. #9
    Registered User
    Join Date
    Sep 2003
    Posts
    224
    I doubt a good compiler would access memory more than twice
    That explains everything. Thanks.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Multithreading (flag stopping a thread, ring buffer) volatile
    By ShwangShwing in forum C Programming
    Replies: 3
    Last Post: 05-19-2009, 07:27 AM
  2. Strange string behavior
    By jcafaro10 in forum C Programming
    Replies: 2
    Last Post: 04-07-2009, 07:38 PM
  3. stop a thread
    By George2 in forum C# Programming
    Replies: 0
    Last Post: 04-22-2008, 03:47 AM
  4. message box and unicode problem
    By Jumper in forum Windows Programming
    Replies: 2
    Last Post: 05-11-2004, 02:53 PM
  5. Tab Controls - API
    By -KEN- in forum Windows Programming
    Replies: 7
    Last Post: 06-02-2002, 09:44 AM