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 in C++

Multithreading in C++

Scheduled Pinned Locked Moved C / C++ / MFC
c++debuggingoopperformancehelp
4 Posts 2 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.
  • T Offline
    T Offline
    TV
    wrote on last edited by
    #1

    Hello, I am trying to do a object oriented multithreaded program with MFC. In order to do that, I have a class CToto whose contructor creates 2 threads with AfxBeginThread. As an argument to AfxBeginThread I pass the this pointer. CToto::CToto() { /...other inits here.../ fastThread = AfxBeginThread((AFX_THREADPROC)ObjectFastThreadRoutine, this); slowThread = AfxBeginThread((AFX_THREADPROC)ObjectSlowThreadRoutine, this); } (The CToto instance is created on the heap with the new operator in the OnInitDialog of a CDialog class.) The thread proc are as follow: UINT ObjectFastThreadRoutine(CToto* lpParam) { lpParam->FastThread(); return 0; } UINT ObjectSlowThreadRoutine(CToto* lpParam) { lpParam->SlowThread(); return 0; } I have therefore two thread running in two members functions of the CToto class. The goal of this approach is to acces to the variables of this class with both threads. To be thread safe, I read and write in the member variables that I want to share with functions which are protected with CCriticalSection objects, here is one of those functions used to write to the positionMeasured member variable of CToto: void CToto::SetPosition(double *pos) { CSingleLock singleLock(critSectionPosition); //critSectionPosition is also a member variable of the class singleLock.Lock(); for(int i=0; i<4; i++) { positionMeasured[i] = pos[i]; } singleLock.Unlock(); } I have three differents member variables such as positionMeasured that are protected like that. All those three variables have Get and Set functions to read and write. My problem occurs when the SlowThread tries to access to the SetPosition function. I have a debug assertion failed at the CSingleLock singleLock(critSectionPosition); line. The assertion is the following: CSingleLock::CSingleLock(CSyncObject* pObject, BOOL bInitialLock) { ASSERT(pObject != NULL); ----> ASSERT(pObject->IsKindOf(RUNTIME_CLASS(CSyncObject))); m_pObject = pObject; m_hObject = pObject->m_hObject; m_bAcquired = FALSE; if (bInitialLock) Lock(); } BOOL CObject::IsKindOf(const CRuntimeClass* pClass) const { ASSERT(this != NULL); // it better be in valid memory, at least for CObject size ------> ASSERT(AfxIsValidAddress(this, sizeof(CObject))); // simple SI case CRuntimeClass* pClassThis = GetRuntimeClass(); return pC

    D 1 Reply Last reply
    0
    • T TV

      Hello, I am trying to do a object oriented multithreaded program with MFC. In order to do that, I have a class CToto whose contructor creates 2 threads with AfxBeginThread. As an argument to AfxBeginThread I pass the this pointer. CToto::CToto() { /...other inits here.../ fastThread = AfxBeginThread((AFX_THREADPROC)ObjectFastThreadRoutine, this); slowThread = AfxBeginThread((AFX_THREADPROC)ObjectSlowThreadRoutine, this); } (The CToto instance is created on the heap with the new operator in the OnInitDialog of a CDialog class.) The thread proc are as follow: UINT ObjectFastThreadRoutine(CToto* lpParam) { lpParam->FastThread(); return 0; } UINT ObjectSlowThreadRoutine(CToto* lpParam) { lpParam->SlowThread(); return 0; } I have therefore two thread running in two members functions of the CToto class. The goal of this approach is to acces to the variables of this class with both threads. To be thread safe, I read and write in the member variables that I want to share with functions which are protected with CCriticalSection objects, here is one of those functions used to write to the positionMeasured member variable of CToto: void CToto::SetPosition(double *pos) { CSingleLock singleLock(critSectionPosition); //critSectionPosition is also a member variable of the class singleLock.Lock(); for(int i=0; i<4; i++) { positionMeasured[i] = pos[i]; } singleLock.Unlock(); } I have three differents member variables such as positionMeasured that are protected like that. All those three variables have Get and Set functions to read and write. My problem occurs when the SlowThread tries to access to the SetPosition function. I have a debug assertion failed at the CSingleLock singleLock(critSectionPosition); line. The assertion is the following: CSingleLock::CSingleLock(CSyncObject* pObject, BOOL bInitialLock) { ASSERT(pObject != NULL); ----> ASSERT(pObject->IsKindOf(RUNTIME_CLASS(CSyncObject))); m_pObject = pObject; m_hObject = pObject->m_hObject; m_bAcquired = FALSE; if (bInitialLock) Lock(); } BOOL CObject::IsKindOf(const CRuntimeClass* pClass) const { ASSERT(this != NULL); // it better be in valid memory, at least for CObject size ------> ASSERT(AfxIsValidAddress(this, sizeof(CObject))); // simple SI case CRuntimeClass* pClassThis = GetRuntimeClass(); return pC

      D Offline
      D Offline
      Diddy
      wrote on last edited by
      #2

      First of all, you are not _really_ using CSingleLock correctly. The point of CSingleLock is to basically aid in cleaning up your critical section if your code throws an exception, or returns take this: fun() { CCriticalSection section; section.lock() . . . if (ladeda) return false; section.unlock(); } here, if the "if (ladeda)" condition was true and you returned, you would be left with a locked CS. - using it this way you have to remeber to unlcok the CS before you return, it makes it harder to use exceptions or to have multiple return points in a function. CSingleLock overcomes that by locking in the constructor and unlocking in the destuctor, so by declaring one on the stack, your CS will automatically be unlocked when that stack unwinds - where ever you may be. You use CSingleLock to overcome the problem like this: fun() { CCriticalSection section; CSingleLock lock(§ion, TRUE). . . if (ladeda) return false; // no need to unlock section, done by ~CSingleLock } In other words, remove the explicate calls to singleLock.Lock(); and singleLock.Unlock(); in your code, and change the decliaration to be CSingleLock singleLock(critSectionPosition, TRUE); - this causes the constructor to call Lock for you. As for your actual problem, well, it depends on what type your critSectionPosition data member is... You haven't included that bit :o) You have to pass a pointer to a CS (or any other sync object) to CSingleObject, the assert is telling you your what you are passing is not of type CSyncObject - ie your not passing a CCritcalSection* which dervices from CSyncObject. If you put up the critSectionPosition data type, I should be able to tell you.

      T 1 Reply Last reply
      0
      • D Diddy

        First of all, you are not _really_ using CSingleLock correctly. The point of CSingleLock is to basically aid in cleaning up your critical section if your code throws an exception, or returns take this: fun() { CCriticalSection section; section.lock() . . . if (ladeda) return false; section.unlock(); } here, if the "if (ladeda)" condition was true and you returned, you would be left with a locked CS. - using it this way you have to remeber to unlcok the CS before you return, it makes it harder to use exceptions or to have multiple return points in a function. CSingleLock overcomes that by locking in the constructor and unlocking in the destuctor, so by declaring one on the stack, your CS will automatically be unlocked when that stack unwinds - where ever you may be. You use CSingleLock to overcome the problem like this: fun() { CCriticalSection section; CSingleLock lock(§ion, TRUE). . . if (ladeda) return false; // no need to unlock section, done by ~CSingleLock } In other words, remove the explicate calls to singleLock.Lock(); and singleLock.Unlock(); in your code, and change the decliaration to be CSingleLock singleLock(critSectionPosition, TRUE); - this causes the constructor to call Lock for you. As for your actual problem, well, it depends on what type your critSectionPosition data member is... You haven't included that bit :o) You have to pass a pointer to a CS (or any other sync object) to CSingleObject, the assert is telling you your what you are passing is not of type CSyncObject - ie your not passing a CCritcalSection* which dervices from CSyncObject. If you put up the critSectionPosition data type, I should be able to tell you.

        T Offline
        T Offline
        TV
        wrote on last edited by
        #3

        I defined critSectionPosition as a pointer and create the object with new in the CToto constructor. I also tried to create it in the stack and I get the same problem. I define my CCriticalSection objects as members of CToto because I have a GetPosition and a SetPosition fonction so I need the same CCriticalSection object to lock the position variable which is accessed by those two function independentely. I juste tried now replacing my CCriticalSection by CMutex and it is working... I know that CMutex are not well suited for my case so I would really like to manage to do that with CCriticalSection. Thanks for your time

        D 1 Reply Last reply
        0
        • T TV

          I defined critSectionPosition as a pointer and create the object with new in the CToto constructor. I also tried to create it in the stack and I get the same problem. I define my CCriticalSection objects as members of CToto because I have a GetPosition and a SetPosition fonction so I need the same CCriticalSection object to lock the position variable which is accessed by those two function independentely. I juste tried now replacing my CCriticalSection by CMutex and it is working... I know that CMutex are not well suited for my case so I would really like to manage to do that with CCriticalSection. Thanks for your time

          D Offline
          D Offline
          Diddy
          wrote on last edited by
          #4

          Hmm, how very strange One thing, the nasty casting to AFX_THREADPROC isn't really a good idea, change your function prototypes to be UINT ThreadProc(LPVOID) and then cast the void paramter to the correct type in the thread. What platform are you using (as in VS.NET/VC6)? Also, try in your SlowThread just calling critsection->Lock() (ie doing away with the CSingleLock class) what happens then?

          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