CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 16
  1. #1
    Join Date
    Jan 2010
    Posts
    49

    How to use Critical Section in MFC ?

    Hi

    I have two worker threads, where one thread(WriteBuf) is writing into buffer and another thread(ReadBuf) is reading from the same buffer.

    I have created CriticalSection object like CCriticalSection m_crit created globaly.

    My thread code looks like below

    UINT WriteBuf(LPVOID pParam)
    {


    crit.Lock();
    buf[0] = 'a'; //Writing to buffer.
    return TRUE;
    }


    UINT ReadBuf(LPVOID pParam)
    {


    buf1[0] = buf[0]; Reading from the buffer.
    TRACE("%c",buf1[0]);
    return TRUE;

    }

    Please let me know is this the rite way to lock the resource(buffer),coz i havent unlocked yet but still i can able to read the buffer from another thread(ReadBuf) .

    So please help me to understand the critical section usage here.

    Thanks
    Abhi

  2. #2
    Join Date
    Jul 2002
    Posts
    2,543

    Re: How to use Critical Section in MFC ?

    Your code is working because ReadBuf doesn't try to lock critical section. But it works without synchronization. Both functions should lock and unlock the same critical section. It is better to do with CSingleLock helper class, which locks critical section in the constructor and unlocks it in the destructor:

    UINT WriteBuf(LPVOID pParam)
    {
    CSingleLock lock(&crit, TRUE);
    buf[0] = 'a'; //Writing to buffer.
    return TRUE;
    }


    UINT ReadBuf(LPVOID pParam)
    {
    CSingleLock lock(&crit, TRUE);
    buf1[0] = buf[0]; Reading from the buffer.
    TRACE("%c",buf1[0]);
    return TRUE;

    }

  3. #3
    Join Date
    Jan 2010
    Posts
    49

    Re: How to use Critical Section in MFC ?

    UINT WriteBuf(LPVOID pParam)
    {

    CSingleLock lock(&crit, TRUE);
    buf[0] = 'a';
    return TRUE;
    }

    UINT ReadBuf(LPVOID pParam)
    {

    buf1[0] = buf[0];
    TRACE("%c",buf1[0]);
    return TRUE;
    }

    In the code above howcome ReadBuf thread is able to access the buffer, because WriteBuf thread is already locked it rite ?

  4. #4
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: How to use Critical Section in MFC ?

    Quote Originally Posted by AbhiMFC View Post
    In the code above how come ReadBuf thread is able to access the buffer, because WriteBuf thread is already locked it rite ?
    Because you aren't protecting the read operation. For you to protect a resource with a critical section, you need to attempt to acquire the cs lock in all operations.

    Code:
    UINT WriteBuf(LPVOID pParam)
    { 
     
        CSingleLock lock(&crit, TRUE);
        buf[0] = 'a';
        return TRUE;
    }
     
    UINT ReadBuf(LPVOID pParam)
    { 
        CSingleLock lock(&crit, TRUE); 
        buf1[0] = buf[0];
        TRACE("%c",buf1[0]);
        return TRUE;
    }

  5. #5
    Join Date
    Jan 2010
    Posts
    49

    Re: How to use Critical Section in MFC ?

    Even after locking the critical section in Readbuf thread i can access the buffer. As u said i have updated the code below .

    UINT WriteBuf(LPVOID pParam)
    {

    CSingleLock lock(&crit, TRUE);
    buf[0] = 'a';
    return TRUE;
    }

    UINT ReadBuf(LPVOID pParam)
    {
    CSingleLock lock(&crit, TRUE);
    buf1[0] = buf[0];
    TRACE("%c",buf1[0]);
    return TRUE;
    }

  6. #6
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: How to use Critical Section in MFC ?

    Quote Originally Posted by AbhiMFC View Post
    Even after locking the critical section in Readbuf thread i can access the buffer.
    Are you using the same critical section? Are you sure you are calling each method from a different thread?

    Btw, if you have 'view signatures' turned on in your control panel, you'll see that I have written several thread synchronization articles. While these don't use the CSingleLock mfc locking class (instead I use a non-MFC RAII helper locking class), they do go over threading basics, show what happens when a resource is shared between thread without synchronization and then introduce synchronization.

  7. #7
    Join Date
    Oct 2007
    Posts
    132

    Re: How to use Critical Section in MFC ?

    Are you sure that both threads are in the critical section at the same time? How do you prove this?

  8. #8
    Join Date
    Jan 2010
    Posts
    49

    Re: How to use Critical Section in MFC ?

    @Arjay

    Iam using same Critical Section object in both the thread. My resource here is a buffer.

    Are you sure you are calling each method from a different thread?

    i didn't understood this question,coz iam not calling any methods from my threads ,just iam using my resources in the threads.

    Coz ReadBuf and Writebuf are two worker threads and it is not a method.
    if incase i have to write methods to work this code,please let me know how to do it.

    Code in Details:-

    void Csamplethread::OnLButtonDown(UINT nFlags,CPoint point)
    {
    AfxBeginThread(WriteBuf,NULL,0,0,0,0); //Thread Writing to the Buffer
    AfxBeginThread(ReadBuf,NULL,0,0,0,0); //Thread Reading from Buffer.
    }


    UINT WriteBuf(LPVOID pParam)
    {

    CSingleLock lock(&crit, TRUE);
    buf[0] = 'a';
    return TRUE;
    }

    UINT ReadBuf(LPVOID pParam)
    {
    CSingleLock lock(&crit, TRUE);
    buf1[0] = buf[0];
    TRACE("%c",buf1[0]);
    return TRUE;
    }

  9. #9
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: How to use Critical Section in MFC ?

    Your WriteBuf thread function exits just after writing to the buf[0] , so there is no lock anymore!
    Victor Nijegorodov

  10. #10
    Join Date
    Jan 2010
    Posts
    49

    Re: How to use Critical Section in MFC ?

    Thanks..

    UINT WriteBuf(LPVOID pParam)
    {

    CSingleLock lock(&crit, TRUE);
    buf[0] = 'a';
    AccesBuffer1();
    return TRUE;
    }


    void CSampletest::AccesBuffer1()

    {

    buf1[0] = buf[0];
    TRACE("%c",buf[0]);
    }

    What about in this case ?
    Iam calling a function where its call the function which access the buffer before its unlocked.

  11. #11
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: How to use Critical Section in MFC ?

    Quote Originally Posted by AbhiMFC View Post
    ...
    What about in this case ?
    Iam calling a function where its call the function which access the buffer before its unlocked.
    Victor Nijegorodov

  12. #12
    Join Date
    Jan 2010
    Posts
    49

    Re: How to use Critical Section in MFC ?

    can u tell me how can i stop accessing to the Resource(buffer) by other threads except WriteBuf().

  13. #13
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: How to use Critical Section in MFC ?

    Quote Originally Posted by AbhiMFC View Post
    can u tell me how can i stop accessing to the Resource(buffer) by other threads except WriteBuf().
    You haven't answered this question:
    Quote Originally Posted by andersod2 View Post
    Are you sure that both threads are in the critical section at the same time? How do you prove this?
    Again: are you sure that your WriteBuf thread is still alive when your ReadBuf is trying to access the buffer?
    According to the code snippets you posted the WriteBuf thread exits immediately after writing to the buffer which leads to unlock this buffer!
    Victor Nijegorodov

  14. #14
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: How to use Critical Section in MFC ?

    Quote Originally Posted by AbhiMFC View Post
    Thanks..

    UINT WriteBuf(LPVOID pParam)
    {

    CSingleLock lock(&crit, TRUE); // Threadsafe for the write part of the operation
    buf[0] = 'a';
    AccesBuffer1();
    return TRUE;
    }


    void CSampletest::AccesBuffer1()

    {

    buf1[0] = buf[0]; // NOT THREADSAFE for reading - DANGER, DANGER
    TRACE("%c",buf[0]);
    }

    What about in this case ?
    Iam calling a function where its call the function which access the buffer before its unlocked.
    I've tried to explain this already, but I'll try again. You need to protect the the shared resource anytime you access if from a different thread. This means you need to protect the resource when writing to it, and reading from it.

  15. #15
    Join Date
    Oct 2007
    Posts
    132

    Re: How to use Critical Section in MFC ?

    Ok, I'm lost now, but that's nothing new. All the lock is doing is preventing both threads from running the critical section *simultaneously* -- that's why I asked how you prove that the code is not behaving as expected. I would need to see some output that proves a race condition or other synchronization error. Otherwise, I would assume that Arjay's first code correction would behave as expected (even though the setup appears a bit odd to me with the thread spawning happening on every button event) --

Page 1 of 2 12 LastLast

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