Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Multithreading using AfxBeginThread

Multithreading using AfxBeginThread

Scheduled Pinned Locked Moved C / C++ / MFC
csharpvisual-studiohelp
14 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Roger Stoltz

    Perhaps it's just a typo, but if not you should be aware of the following: There's a big risk the thread will never exit as you've failed to declare the m_bWorking variable as volatile. It depends on your optimization settings. The compiler may choose to hold the variable in a register in the while-loop, not reading it from its actual memory location since it's not being modified in the while-loop. Declaring it as volatile will tell the compiler that the variable must be read from its memory location and cannot be optimized into a register.

    "It's supposed to be hard, otherwise anybody could do it!" - selfquote
    "High speed never compensates for wrong direction!" - unknown

    E Offline
    E Offline
    Eugen Podsypalnikov
    wrote on last edited by
    #5

    Wow, I did not know it ! Thank you very much, Roger ! :) :thumbsup: As possible "workaround" could be also the usage of a limitation function:

    bool CYourDialog::IsWorking() {
    return m_bWorking;
    }

    virtual void BeHappy() = 0;

    R 1 Reply Last reply
    0
    • E Eugen Podsypalnikov

      Wow, I did not know it ! Thank you very much, Roger ! :) :thumbsup: As possible "workaround" could be also the usage of a limitation function:

      bool CYourDialog::IsWorking() {
      return m_bWorking;
      }

      virtual void BeHappy() = 0;

      R Offline
      R Offline
      Roger Stoltz
      wrote on last edited by
      #6

      Eugen Podsypalnikov wrote:

      Wow, I did not know it ! Thank you very much, Roger !

      :) You're most welcome.

      Eugen Podsypalnikov wrote:

      As possible "workaround" could be also the usage of a limitation function:

      bool CYourDialog::IsWorking() {
      return m_bWorking;
      }

      Naah, I wouldn't count on that. This also depends on your optimization settings... ;) There's a compiler switch that tells the compiler to expand "any suitable" function as inline, which would generate the same code as if you would have referenced the variable directly even though you haven't declared the function explicitly as inline. Then you would be back to square one, with the possibility that the variable could be optimized into a register.

      "It's supposed to be hard, otherwise anybody could do it!" - selfquote
      "High speed never compensates for wrong direction!" - unknown

      E 1 Reply Last reply
      0
      • R Roger Stoltz

        Eugen Podsypalnikov wrote:

        Wow, I did not know it ! Thank you very much, Roger !

        :) You're most welcome.

        Eugen Podsypalnikov wrote:

        As possible "workaround" could be also the usage of a limitation function:

        bool CYourDialog::IsWorking() {
        return m_bWorking;
        }

        Naah, I wouldn't count on that. This also depends on your optimization settings... ;) There's a compiler switch that tells the compiler to expand "any suitable" function as inline, which would generate the same code as if you would have referenced the variable directly even though you haven't declared the function explicitly as inline. Then you would be back to square one, with the possibility that the variable could be optimized into a register.

        "It's supposed to be hard, otherwise anybody could do it!" - selfquote
        "High speed never compensates for wrong direction!" - unknown

        E Offline
        E Offline
        Eugen Podsypalnikov
        wrote on last edited by
        #7

        Yes, saved... :) Thank you - for the both explanations, Roger !

        virtual void BeHappy() = 0;

        1 Reply Last reply
        0
        • E Eugen Podsypalnikov

          kartikthakre wrote:

          but it is working if i am passing function pointer of any static function or global function

          That is also the "classical" way to pass - for example - a private static function of a dialog... :)

          // .h
          ...
          class CYourDialog : public CDialog
          {
          bool m_bWorking;
          CWinThread* m_pcThread;
          static DWORD WINAPI ThreadProc(CYourDialog*);
          ...
          public:
          CYourDialog(CWnd* pcParent = NULL);
          ~CYourDialog();
          ...
          void On();
          void Off();
          ...
          };
          // .cpp
          ...
          CYourDialog::CYourDialog(CWnd* pcParent /*= NULL*/)
          : CDialog(CYourDialog::IDD, pcParent),
          m_bWorking(false),
          m_pcThread(NULL)
          {
          ...
          }
          CYourDialog::~CYourDialog()
          {
          Off();
          }
          CYourDialog::On()
          {
          if (!m_bWorking && !m_pcThread) {
          m_bWorking = true;
          m_pcThread = AfxBeginThread(ThreadProc, this);
          }
          }
          CYourDialog::Off()
          {
          if (m_bWorking && m_pcThread) {
          m_bWorking = false;
          WaitForSingleObject(m_pcThread->m_hThread, INFINITE);
          m_pcThread = NULL;
          }
          }
          DWORD WINAPI CYourDialog::ThreadProc(CYourDialog* pcDlg)
          {
          while (pcDlg && pcDlg->m_bWorking) {
          // Do something
          Sleep(1);
          }
          return 0;
          }

          virtual void BeHappy() = 0;

          modified on Thursday, April 1, 2010 2:42 AM

          D Offline
          D Offline
          David Crow
          wrote on last edited by
          #8

          Eugen Podsypalnikov wrote:

          DWORD WINAPI CYourDialog::ThreadProc(CYourDialog* pcDlg)

          Shouldn't this be:

          UINT CYourDialog::ThreadProc( LPVOID pcDlg )

          "One man's wage rise is another man's price increase." - Harold Wilson

          "Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons

          "Man who follows car will be exhausted." - Confucius

          E 1 Reply Last reply
          0
          • D David Crow

            Eugen Podsypalnikov wrote:

            DWORD WINAPI CYourDialog::ThreadProc(CYourDialog* pcDlg)

            Shouldn't this be:

            UINT CYourDialog::ThreadProc( LPVOID pcDlg )

            "One man's wage rise is another man's price increase." - Harold Wilson

            "Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons

            "Man who follows car will be exhausted." - Confucius

            E Offline
            E Offline
            Eugen Podsypalnikov
            wrote on last edited by
            #9

            Yes, of course :) You could use my declaration too and pass it by the casting (AFX_THREADPROC) , so you can use its parameter pcDlg without casting... :)

            virtual void BeHappy() = 0;

            1 Reply Last reply
            0
            • E Eugen Podsypalnikov

              kartikthakre wrote:

              but it is working if i am passing function pointer of any static function or global function

              That is also the "classical" way to pass - for example - a private static function of a dialog... :)

              // .h
              ...
              class CYourDialog : public CDialog
              {
              bool m_bWorking;
              CWinThread* m_pcThread;
              static DWORD WINAPI ThreadProc(CYourDialog*);
              ...
              public:
              CYourDialog(CWnd* pcParent = NULL);
              ~CYourDialog();
              ...
              void On();
              void Off();
              ...
              };
              // .cpp
              ...
              CYourDialog::CYourDialog(CWnd* pcParent /*= NULL*/)
              : CDialog(CYourDialog::IDD, pcParent),
              m_bWorking(false),
              m_pcThread(NULL)
              {
              ...
              }
              CYourDialog::~CYourDialog()
              {
              Off();
              }
              CYourDialog::On()
              {
              if (!m_bWorking && !m_pcThread) {
              m_bWorking = true;
              m_pcThread = AfxBeginThread(ThreadProc, this);
              }
              }
              CYourDialog::Off()
              {
              if (m_bWorking && m_pcThread) {
              m_bWorking = false;
              WaitForSingleObject(m_pcThread->m_hThread, INFINITE);
              m_pcThread = NULL;
              }
              }
              DWORD WINAPI CYourDialog::ThreadProc(CYourDialog* pcDlg)
              {
              while (pcDlg && pcDlg->m_bWorking) {
              // Do something
              Sleep(1);
              }
              return 0;
              }

              virtual void BeHappy() = 0;

              modified on Thursday, April 1, 2010 2:42 AM

              K Offline
              K Offline
              kartikthakre
              wrote on last edited by
              #10

              Thanks for reply, But i already written that it is working for static and global function. What i want is that it is work for member function. I am waiting for reply thanks

              D 1 Reply Last reply
              0
              • D David Crow

                Is MyThreadProc() a static member of CMultithreadingInDialogDlg?

                "One man's wage rise is another man's price increase." - Harold Wilson

                "Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons

                "Man who follows car will be exhausted." - Confucius

                K Offline
                K Offline
                kartikthakre
                wrote on last edited by
                #11

                MyThreadProc is not a static function, it is simple member function.

                D 1 Reply Last reply
                0
                • K kartikthakre

                  MyThreadProc is not a static function, it is simple member function.

                  D Offline
                  D Offline
                  David Crow
                  wrote on last edited by
                  #12

                  Which means it cannot be used an argument to AfxBeginThread().

                  "One man's wage rise is another man's price increase." - Harold Wilson

                  "Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons

                  "Man who follows car will be exhausted." - Confucius

                  1 Reply Last reply
                  0
                  • K kartikthakre

                    Thanks for reply, But i already written that it is working for static and global function. What i want is that it is work for member function. I am waiting for reply thanks

                    D Offline
                    D Offline
                    David Crow
                    wrote on last edited by
                    #13

                    kartikthakre wrote:

                    What i want is that it is work for member function.

                    You can't do it directly. What you'll have to do is:

                    void CMyDlg::ThreadProc( void )
                    {
                    ...
                    }

                    UINT ThreadProc( LPVOID lpParam )
                    {
                    CMyDlg *pDlg = (CMyDlg *) lpParam;

                    pDlg->ThreadProc();
                    
                    return 0;
                    

                    }

                    static UINT CMyDlg::ThreadProc( LPVOID lpParam )
                    {
                    CMyDlg *pDlg = (CMyDlg *) lpParam;

                    pDlg->ThreadProc();
                    
                    return 0;
                    

                    }

                    AfxBeginThread(ThreadProc, this); // static member
                    AfxBeginThread(::ThreadProc, this); // global

                    "One man's wage rise is another man's price increase." - Harold Wilson

                    "Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons

                    "Man who follows car will be exhausted." - Confucius

                    K 1 Reply Last reply
                    0
                    • D David Crow

                      kartikthakre wrote:

                      What i want is that it is work for member function.

                      You can't do it directly. What you'll have to do is:

                      void CMyDlg::ThreadProc( void )
                      {
                      ...
                      }

                      UINT ThreadProc( LPVOID lpParam )
                      {
                      CMyDlg *pDlg = (CMyDlg *) lpParam;

                      pDlg->ThreadProc();
                      
                      return 0;
                      

                      }

                      static UINT CMyDlg::ThreadProc( LPVOID lpParam )
                      {
                      CMyDlg *pDlg = (CMyDlg *) lpParam;

                      pDlg->ThreadProc();
                      
                      return 0;
                      

                      }

                      AfxBeginThread(ThreadProc, this); // static member
                      AfxBeginThread(::ThreadProc, this); // global

                      "One man's wage rise is another man's price increase." - Harold Wilson

                      "Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons

                      "Man who follows car will be exhausted." - Confucius

                      K Offline
                      K Offline
                      kartikthakre
                      wrote on last edited by
                      #14

                      but what is the region, so that member function pointer is not pass to AfxBeginThread.

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups