cout and multithreading

This is a discussion on cout and multithreading within the C++ Programming forums, part of the General Programming Boards category; So I noticed an issue tonight while testing a multithreaded program. In the effect of if two threads both try ...

  1. #1
    Registered User ~Kyo~'s Avatar
    Join Date
    Jun 2004
    Posts
    320

    cout and multithreading

    So I noticed an issue tonight while testing a multithreaded program. In the effect of if two threads both try to cout at the same time they cut into each other, but not only that - it seems to have broken cout as all output to the console after that point never showed up. I use endl which if I remember flushes the stream after the call which doesn't clear the issue up. I am jsut curious what would be locked to keep the system from doing this to itself. For now I am removing the older cout as it was there for letting me know a connection was being culled from the server and the new one does the same just a bit more implementation specific. Looks like it broke fstream as well as the output file is mangled.... lol.
    Last edited by ~Kyo~; 09-17-2011 at 02:07 AM. Reason: Adding more info

  2. #2
    Registered User whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    7,763
    You could lock your stream buffers I guess, but to tell the whole truth, I'm not sure how much this will solve the problem.

    ios::rdbuf - C++ Reference

    Perhaps you could stuff the output in a stringstream buffer for each thread and just flush or read when the thread has control? If you don't share that data between threads it should alleviate the issue.

  3. #3
    Registered User ~Kyo~'s Avatar
    Join Date
    Jun 2004
    Posts
    320
    Will give that a shot thanks.

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,679
    Quote Originally Posted by whiteflags View Post
    You could lock your stream buffers I guess, but to tell the whole truth, I'm not sure how much this will solve the problem.
    It won't. No object (and that includes stream buffers) can protect itself from concurrent access. If two threads are concurrently accessing an object, those two threads need to synchronise access to the object.

    Quote Originally Posted by whiteflags View Post
    Perhaps you could stuff the output in a stringstream buffer for each thread and just flush or read when the thread has control? If you don't share that data between threads it should alleviate the issue.
    The trick to alleviate the issue is for each thread to synchronise their access (for example, using a mutex to determine which thread "has control") to the stream.

    Each thread maintaining their own buffer can help, by reducing how often each thread needs to access the stream.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Sunshine, and read this, this, and this before posting again.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    23,033
    To my knowledge, the entire STL library is not thread safe (I could be wrong; there may be some exceptions). That simply means you must make sure to only access the same object from one thread at a time.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User
    Join Date
    Oct 2006
    Posts
    2,590
    Quote Originally Posted by grumpy View Post
    No object (and that includes stream buffers) can protect itself from concurrent access.
    you could certainly code a class so that it contains a mutex or some other locking construct as a member, and any attempt to perform an operation on an object of that type would implicitly attempt to lock that mutex, guaranteeing safe concurrent access. not sure if this is good practice, or if it's better for the coder to explicitly lock an object before attempting an operation on that object.

  7. #7
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by ~Kyo~ View Post
    So I noticed an issue tonight while testing a multithreaded program. In the effect of if two threads both try to cout at the same time they cut into each other, but not only that - it seems to have broken cout as all output to the console after that point never showed up. I use endl which if I remember flushes the stream after the call which doesn't clear the issue up. I am jsut curious what would be locked to keep the system from doing this to itself. For now I am removing the older cout as it was there for letting me know a connection was being culled from the server and the new one does the same just a bit more implementation specific. Looks like it broke fstream as well as the output file is mangled.... lol.
    On what operating system?

    In Windows you would use Critical Sections... Critical Section Objects (Windows)

    As in...
    Code:
    ThreadSafePrint()
        EnterCriticalSection()
            print your stuff
        ExitCricicalSection()
    ... and everything prints through that routine.
    Last edited by CommonTater; 09-17-2011 at 10:46 PM.

  8. #8
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    4,415
    You can always try `std::ios::sentry', but it isn't guaranteed to do any strong locking.

    Soma

  9. #9
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    1,625
    The mischievous way:
    Code:
    #include <iostream>
    #include <process.h> // Is this the one?
    
    using namespace std;
    
    volatile bool done_printing = false;
    
    void printFirst(void*);
    void printSecond();
    
    int main()
    {
        _beginthread(printFirst, 0, 0);
    
        while (!done_printing);
    
        printSecond();
    
        return 0;
    }
    
    void printFirst(void*)
    {
        cout << "This prints first!\n";
        done_printing = true;
     
        _endthread();
    }
    
    void printSecond()
    {
        cout << "This prints second!\n";
    }
    Warning: Untested! Use it at your own peril!!
    Devoted my life to programming...

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    23,033
    Quote Originally Posted by CommonTater View Post
    On what operating system?

    In Windows you would use Critical Sections... Critical Section Objects (Windows)

    As in...
    Code:
    ThreadSafePrint()
        EnterCriticalSection()
            print your stuff
        ExitCricicalSection()
    ... and everything prints through that routine.
    You need to stop using your C stuff. It's not exception safe, and it's not programmer safe. It's just unsafe all around! There is no reason at all to use it. One mistake and you get a deadlock.
    Use boost, or the standard library for C++!

    Sipher:
    Your code is unsafe. It creates a race condition and it uses a busy loop, which is even worse.
    There are perfectly standardized threading threading tools available, such as std::thread or boost::thread. They even have locks to prevent race conditions and allows you to actually wait for threads to complete instead of using busy loops.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    1,625
    Quote Originally Posted by Elysia View Post
    Your code is unsafe. It creates a race condition and it uses a busy loop, which is even worse.
    There are perfectly standardized threading threading tools available, such as std::thread or boost::thread. They even have locks to prevent race conditions and allows you to actually wait for threads to complete instead of using busy loops.
    Of course, I was just throwing an other idea. My example is neither practical nor sane for large implementations, but in this code it wouldn't hurt anyone...
    Devoted my life to programming...

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    23,033
    Quote Originally Posted by Sipher View Post
    ...but in this code it wouldn't hurt anyone...
    But that is where I disagree.
    Your code is broken in that it relies on race conditions.
    And the fact that it uses a busy loop is unacceptable--at least to me--under any circumstance unless you can prove there is no better way to do it.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by GReaper View Post
    Of course, I was just throwing an other idea. My example is neither practical nor sane for large implementations, but in this code it wouldn't hurt anyone...
    No, you are wrong. I had ideas like this the first time I wrote a multi-threaded program, I'm sure a lot of people do because it seems like an obvious solution. I was wrong. You cannot attempt operations across threads without a thread-safe locking mechanism. This includes accessing simple variables. Why? How could, eg, a single byte value get messed up?

    Here's how: done_printing is true. Thread A, running on core 1, loads the true value from RAM, meaning it can print. Great. Meanwhile, Thread B, running on core 2, loads the same true value from RAM, meaning it can print. Not so great. Now both threads set done_printing to false and proceed to screw up.

    So all your idea does is move the problem from one place to a different place, and when that goes wrong, the original problem will re-emerge.

    @Kyo: You did not say what thread implementation you are using, but all of them have thread-safe locking mechanisms, because without such they would be near useless. Use them when you perform IO on a global stream such as stdout, just as you would use them when reading from or writing to any structure accessed by more than one thread. There are no other choices, that's how threads work.
    Last edited by MK27; 09-18-2011 at 10:04 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  14. #14
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    1,625
    Quote Originally Posted by MK27 View Post
    This includes accessing simple variables. So all your idea does is move the problem from one place to a different place, and when that goes wrong, the original problem will re-emerge. End of story.
    I didn't catch that part. What do you mean? Sure, my idea is a total crap but what exactly is the problem?!

    EDIT: Oh, I read your addition...
    Devoted my life to programming...

  15. #15
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    1,625
    Quote Originally Posted by MK27 View Post
    Here's how: done_printing is true. Thread A, running on core 1, loads the true value from RAM, meaning it can print. Great. Meanwhile, Thread B, running on core 2, loads the same true value from RAM, meaning it can print. Not so great. Now both threads set done_printing to false and proceed to screw up.
    Oh, NOW I understand what you're saying! That's not the case, you see, because only one thread changes the variable and only the other reads it.
    Last edited by GReaper; 09-18-2011 at 10:33 AM.
    Devoted my life to programming...

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Multithreading.
    By kevinawad in forum C++ Programming
    Replies: 5
    Last Post: 10-21-2008, 01:12 PM
  2. std::cout or using namespace std or using std::cout
    By ComDriver in forum C++ Programming
    Replies: 13
    Last Post: 01-31-2005, 11:54 AM
  3. Whats the difference between cout and std::cout?
    By mdshort in forum C++ Programming
    Replies: 10
    Last Post: 12-30-2003, 05:34 PM
  4. multithreading
    By thedumbmutt in forum A Brief History of Cprogramming.com
    Replies: 1
    Last Post: 11-13-2002, 11:54 AM
  5. Multithreading :: MFC
    By kuphryn in forum Windows Programming
    Replies: 2
    Last Post: 10-03-2002, 09:39 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21