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.
  • 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

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

    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 1 Reply Last reply
    0
    • 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