CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 2 of 3 FirstFirst 123 LastLast
Results 16 to 30 of 31
  1. #16
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: Critical Sections and Read operations.

    Quote Originally Posted by ProgrammerC++ View Post
    Show me with good examples that I'm wrong, please.
    That's not the way things work. If you want to know if your code is thread safe, you don't ask someone else to show that it's not thread safe, you analyze the code to prove that it is thread safe. That start with making all assumptions clear, which is something you haven't done in any of your posts in this thread, thereby creating needless confusion.

    Now, I'm not sure if your code will be thread safe on a particular version of a particular compiler. Again, that's not up to me to disprove. However, I do know that your code is not thread safe in general - for the reason mentioned numerous times above. That means that if you use this, you're not guaranteed it will work with another compiler, with another version of the same compiler or even with different compiler settings. So why use it, let alone advice other people to use it?
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  2. #17
    Join Date
    Nov 2003
    Posts
    1,902

    Re: Critical Sections and Read operations.

    >> Show me with good examples that I'm wrong, please.
    Your example will do just fine. Since you don't believe that, what good is another example?

    There is no guarantee that any of the threads will see 'closeworkerthreads' change value. Your observation with your particular compiler is no guarantee.

    Posix and C++0x are the only standards I know that cover multi-threading. Your code has undefined behavior under both.

    If you want to make your code correct for any Win32 compiler, you need to use a Win32 synchronization primitive - like an interlocked function or a critical section etc...

    gg

  3. #18
    Join Date
    Jul 2009
    Posts
    154

    Re: Critical Sections and Read operations.

    gg

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

    Re: Critical Sections and Read operations.

    Quote Originally Posted by ProgrammerC++ View Post
    I think both of you above me don't know that a race condition can't occur when there's 1 thread writing to 1 boolean and all other threads only read the boolean
    Actually I understand this very well. If the shared resource is a boolean which can be changed in an atomic operation, then no race condition will occur. This is the one special case where no synchronizating is required.

    However, every other variable (BOOL, int, string, etc), you will encounter a race condition if one thread writes while one or more threads are reading or writing.

    When I answered this question, I'm not interested in talking about the one special case (i.e. boolean) where sharing a resource across threads works without synchronization.

    Folks tend to find thread synchronizating hard enough as it is. To me, it's easier to try to list the rules where you need synchronization:

    1) If at least one thread is writing while one or more threads are reading or writing, then you need synchronization.
    2) If all threads only every read, then no synchronization is required.

    It's easier to apply these rules to all variables/shared resources including a boolean type. For the boolean, synchronization isn't technically required, but doesn't hurt.

    As far as boolean, I never use these sorts of flag variables anyway to signal the thread to perform some action. Instead I'll use a windows event. Advantages of using an events are they can be used in the WaitFor functions and they can be used across processes.

  5. #20
    Join Date
    Nov 2003
    Posts
    1,902

    Re: Critical Sections and Read operations.

    >> If the shared resource is a boolean which can be changed in an atomic operation, then no race condition will occur.
    That is still an [x86] generalization that doesn't account for memory-visibility and cache-coherency algorithms that other architectures may employ. In other words, an [atomic] write is of little use if another core never "sees" that write.

    For x86 architectures, I believe it is safe to say that a store to memory by one core will eventually be "seen" (via a load) by other cores. But that is thanks to the x86 cache coherency protocol.

    >> For the boolean, synchronization isn't technically required, but doesn't hurt.
    The only way I can agree with this statement is to qualify it with "on x86 hardware, using assembly language - or compiler documented extensions ".

    gg

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

    Re: Critical Sections and Read operations.

    Quote Originally Posted by Codeplug View Post
    >> If the shared resource is a boolean which can be changed in an atomic operation, then no race condition will occur.
    That is still an [x86] generalization that doesn't account for memory-visibility and cache-coherency algorithms that other architectures may employ. In other words, an [atomic] write is of little use if another core never "sees" that write.

    For x86 architectures, I believe it is safe to say that a store to memory by one core will eventually be "seen" (via a load) by other cores. But that is thanks to the x86 cache coherency protocol.

    >> For the boolean, synchronization isn't technically required, but doesn't hurt.
    The only way I can agree with this statement is to qualify it with "on x86 hardware, using assembly language - or compiler documented extensions ".

    gg
    That's great. I generally don't rely on any type to synchronize themselves. Last I checked on booleans, they were atomic but that doesn't really matter to me for two reasons. 1) I'm looking for a generic solution that works regardless of the type of shared resource. 2) I have never found a need to synchronize a bool. I never use flag variables, so I never synchronize booleans.

    Finally, I'm always looking for a solution that doesn't require me to have hardware specific knowledge. If I use a critical section to synchronize, I know it will work across Windows.

  7. #22
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: Critical Sections and Read operations.

    Quote Originally Posted by ProgrammerC++ View Post
    ....
    Code:
    pseudo code
    
    Destructor::~Destructor()
    {
       bThreadContinue = FALSE; //Local var of class
    
       for all threads
       {
            ResumeThread( HandleToThread ); // if the thread is in suspended mode
            WaitForSingleObject( HandleToThread, INFINITE );
            CloseHandle( HandleToThread );
       }
    }
    Just an aside to the main conversation, ResumeThread(), like SuspendThread(), should never be used in any Windows programming.

    There is one exception, but it's a very narrow one, unlikely to be encountered frequently. The exception is this: if you are writing a debugger for other programs, then you may use Suspend/ResumeThread on the threads of the other programs.

    The documentation explains this clearly.

    Mike

  8. #23
    Join Date
    Jul 2009
    Posts
    154

    Re: Critical Sections and Read operations.

    Actually the documentation says SuspendThread can be used but only by the thread itself.

    ..signal the other thread to suspend itself...
    I believe Suspending a thread is better (on itself) is better than to use something like WaitForSingleObject(event, infinite) because when a thread is suspended 0 CPU is used ever on that thread while I think for WaitForSingleObject still probably uses abit CPU to keep checking the state of the event.

    This is not documented though but sounds most logic

  9. #24
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Critical Sections and Read operations.

    Quote Originally Posted by ProgrammerC++ View Post
    I think both of you above me don't know that a race condition can't occur when there's 1 thread writing to 1 boolean and all other threads only read the boolean
    In the specific case of using a boolean to let a thread know it's okay to terminate, this may to be true. In fact, it probably is on most compilers.

    However, this relies on the writer thread not needing to do anything critical after modifying the boolean, only before. In the other case, you certainly *can* get a race condition:

    Code:
    Thread 1 (writer):
    
    stopWriting = true;
    write file summary to end of file
    
    Thread 2 (reader):
    
    while (!stopWriting)
        write record to end of file
    Here, thread 1 has no way of knowing when it's safe to actually proceed and write the file footer, so this is a race condition.

    The lesson is: it's possible to write lock-free code, and very occasionally necessary, but as a rule of thumb: lock everything that even *might* need it. You'll suffer far less grief with a slight performance hit than spending 10 hours searching for an elusive Hiesenbug because you thought you didn't need to lock something.

  10. #25
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: Critical Sections and Read operations.

    Quote Originally Posted by ProgrammerC++ View Post
    Actually the documentation says SuspendThread can be used but only by the thread itself.
    I think you have missed the main point, which is not to call SuspendThread ever, unless you fall into one narrow exception that is unlikely to be encountered by most Windows programmers.

    The documentation is clear and unambiguous, and includes the following warning (from "SuspendThread Function" at http://msdn.microsoft.com/en-us/libr...8VS.85%29.aspx):
    Quote Originally Posted by MSDN
    This function is primarily designed for use by debuggers. It is not intended to be used for thread synchronization.
    It doesn't really matter what follows after this warning. It's enough to know that SuspendThread "is not intended to be used for thread synchronization". If you are using SuspendThread for thread synchronization, then you are probably doing something wrong.
    Quote Originally Posted by ProgrammerC++ View Post
    I believe Suspending a thread is better (on itself) is better than to use something like WaitForSingleObject(event, infinite) because when a thread is suspended 0 CPU is used ever on that thread while I think for WaitForSingleObject still probably uses abit CPU to keep checking the state of the event.

    This is not documented though but sounds most logic
    This conclusion seems unfounded. The documentation also states that it is the user-mode code for a thread that's suspended. Just like WFSO, it's probable that kernel-mode code is still executed: in the case of WFSO, a check for the event, and in the case of SuspendThread, a check of the suspend count.

    But even if a Suspend'edThread is somehow "more suspended" than a WFSO thread, that's hardly a reason to use it improperly, for purposes of thread synchronization, in the face of the admonition of Microsoft not to.

    Mike

  11. #26
    Join Date
    Jul 2009
    Posts
    154

    Re: Critical Sections and Read operations.

    I use SuspendThread on a thread that's used for each socket to be the receiver for that socket.

    If the thread is waiting for a new socket to handle its inside SuspendThread and another thread will simply say ResumeThread to tell it its socket is ready to receive (so on connect or accept).

    blocking socket (blocking recv()) obviously.

    after the socket is closed the thread goes back in SuspendThread and there we start again.

    I guess I could achieve the same result with Events and WaitForSingleObject but at the time I wrote that I didnt know of these functions. I don't think rewriting will make any positive difference anyway (only negative since it costs time to implement and test)
    Last edited by ProgrammerC++; August 16th, 2010 at 11:55 PM.

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

    Re: Critical Sections and Read operations.

    Quote Originally Posted by ProgrammerC++ View Post
    I don't think rewriting will make any positive difference anyway (only negative since it costs time to implement and test)
    On the other hand, you have a current problem and have been offerred an alternate approach to solve the problem. If you want to solve the problem, it seems worth it to try the new approach.

    Or you could do nothing.

    The choice seems obvious.

  13. #28
    Join Date
    Jan 2006
    Posts
    8

    Re: Critical Sections and Read operations.

    guys, could you please recomend some books (THREADS)
    thnks !

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

    Re: Critical Sections and Read operations.

    For Windows, the following book is the process and threading standard:

    Programming Applications For Microsoft Windows by Jeffrey Richter

  15. #30
    Join Date
    Oct 2009
    Posts
    577

    Smile Re: Critical Sections and Read operations.

    Quote Originally Posted by Arjay View Post
    Not so. You get a race condition if one or more thread write, while other threads are reading (or writing).

    Why is thread synchronization so difficult?
    Wikipedia defines the race condition as

    A race condition or race hazard is a flaw in an electronic system or process whereby the output and/or result of the process is unexpectedly and critically dependent on the sequence or timing of other events. The term originates with the idea of two signals racing each other to influence the output first.
    In case a (main) thread sets a shared boolean variable to true while multiple threads make a periodically check on that boolean therefore isn't a race condition. There is nothing unexpectedly and critically added when one of the threads reads the 'true' in the next period.

    An atomic operation on a shared variable is only required if you want to be able to write from more than one thread and make sure that the second writer was reading the current value written by the frist writer. That normally only makes sense if you increment an integer or toggle a boolean cause if the writers don't (have to) care for the old contents (and that behavior isn't an error ) it actually isn't a race condition despite of two writers cause the result written is arbitrary anyhow depending on which thread was first or second.

    In case of an incrementation or toggle you need synchronisation or an atomic setting cause otherwise you couldn't prevent from the case that two threads both do increment/toggle the old value hence one incrementation/toggle gets lost what is a race condition.

    BTW, if the operation system offers an atomic incrementation (e. g. InterlockedIncrement of WINAPI) the atomic operation is guaranteed also for multi-processor and multi-core architectures. But of course on the latter systems an i++ in general isn't an atomic operation.

Page 2 of 3 FirstFirst 123 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