I am writing a course on modern C++ and wanting to explain how the flush operations work, so I decided to disable the automatic flush in order to write to the buffer only when std::cout is destroyed.
For that, only one standard function exists and it is the manipulator std::nounitbuf.
However, this doesn't work on MSVC.
What surprises me the most is that the alternative in C, the setvbuf function, actually allows you to deactivate the automatic flush.
It bothers me a little because I want to teach C++ and not C.
Can anyone help me? thank you!
#include <iostream>
#include <thread>
int main()
{
std::cout << std::nounitbuf; // doesn't work (output is two Hello World before the 5 seconds delay)
//setvbuf(stdout, nullptr, _IOFBF, BUFSIZ); // work (output is one Hello World, then another one after the 5 seconds)
std::cout << "Hello World" << std::endl;
std::cout << "Hello World";
std::this_thread::sleep_for(std::chrono::seconds{ 5 });
}
Why std::nounitbuf doesn't do anything?
Most probably because unitbuf flag is not set by default for standard cout stream. (Standard narrow.stream.objects requires it should be set only for cerr).
Can anyone help me?
C++ are synchronized (not buffered) with stdio streams. What you write std::cout << "something" goes straight to FILE* stdout. As it goes straight there, stdout buffering is all that matters.
Disable synchronization with stdio streams and try then. Read about std::ios::sync_with_stdio. The following works for me.
#include <iostream>
#include <thread>
int main() {
std::ios::sync_with_stdio(false);
std::cout << "Hello World" << std::endl;
std::cout << "Hello World\n";
std::this_thread::sleep_for(std::chrono::seconds{ 5 });
}
From: https://en.cppreference.com/w/cpp/io/manip/endl
In many implementations, standard output is line-buffered, and writing
'\n' causes a flush anyway, unless std::ios::sync_with_stdio(false)
was executed.
Try to remove std::endl and '\n' from the output and you will get the desired behavior. And as Marek said, std::nounitbuf is default setting for std::cout.
Related
In C++20 we got a new thread-class std::jthread that unlike old std::thread
waits
for thread termination in the destructor. So it becomes easy to execute several actions in parallel using unnamed jthread-objects and comma operator:
#include <thread>
#include <iostream>
int main() {
std::jthread{ []{ std::cout << "Hello from new thread\n"; } },
std::cout << "Hello from main thread\n";
}
This works fine, demo: https://gcc.godbolt.org/z/YPW8bq7jK
Unfortunately, Visual Studio 2019 issues a warning here:
warning C4834: discarding return value of function with 'nodiscard' attribute
because std::jthread constructor is declared as [[nodiscard]] in it. As far as I see the standard does not require this attribute: https://timsong-cpp.github.io/cppwp/n4861/thread.jthread.class.
Is it just a bug in MSVC STL, or there is really some risk associated with such jthread-usage?
there is really some risk associated with such jthread-usage?
Define "such usage" and "some risk".
The nodiscard attribute is entirely appropriate for jthread's constructors. Yes, you can write code where creating and discarding a jthread object is a meaningful, functional thing. But even if it is meaningful and functional, you still shouldn't do it. It's being cute in your code in a way that adds absolutely nothing of value. It looks like a bug, and its best not to write code that looks almost identical to broken code.
Try to write clear, clean code that doesn't require someone to know the intimate details of the C++ comma operator and its relationship to subexpressions in order to accurately gauge its operation.
And yes, standard library implementations are allowed to give warnings for any reason. So long as well-formed programs successfully compile and execute as described by the standard, the implementation is valid.
Why not write it like this?
#include <thread>
#include <iostream>
int main()
{
// Note: Just like the original
// It is indeterminate what order these are
// printed out in.
std::jthread parallelThread{ []{ std::cout << "Hello from new thread\n"; } };
std::cout << "Hello from main thread\n";
}
This does exactly the same, but uses a named variable rather an invisible temporary.
As a side note you can force order by making sure you know when the jthread is destroyed.
#include <thread>
#include <iostream>
int main()
{
{
std::jthread parallelThread{ []{ std::cout << "Hello from new thread\n"; } };
}
std::cout << "Hello from main thread\n";
}
For cpp, I know that we have three cases to flush the buffer:
When we get std::cin
When we std::cout<<std::endl (or ohters things like endl)
When we call some function like fflush
If I am right, there is a question:
If I just write std::cout<<"hello world"; in main and run it, I could see "hello world" at the console. So, by whom and when does the buffer flush? By the compiler? Or the buffer will flush when the main finishes?
You probably want to read about std::unitbuf and std::nounitbuf. Here's a decent reference.
It might be helpful to play with some simple examples. For instance, the following code will not print Hello world ever, because there won't be automatic flushing of the output stream after any output operation:
EXAMPLE 1
#include<iostream>
int main()
{
// ----- Don't want automatic flushing ------
std::cout << std::nounitbuf;
std::cout << "Hello world";
while (1)
{
;
}
}
And this code example will indeed print Hello world, because I specified that I want the automatic flushing to be enabled:
EXAMPLE 2
#include<iostream>
int main()
{
// ----- I do want automatic flushing ------
std::cout << std::unitbuf;
std::cout << "Hello world";
while (1)
{
;
}
}
I know that the infiite while loop looks a bit silly, but it's the easiest and most portable way of pausing the code that I can think of right now (I'm sure there are better ways, though!). This way I don't get flushing because of (1) code termination, (2) destructors being called and (3) so on. It's all down to the properties of std::cout.
Stumbling on the same question, I made a little test
int main() {
printf("t");
// fflush(stdout);
while(1);
return 0;
}
It appears that without the fflush, nothing is printed out.
With the flush, my little "t" appears on the console.
So, adding to the previous response, I believe flushing doesn't happen magically, but with the help of various "events", for example when the program exits, or when the buffer is full.
This answer helped me a lot understand it.
Why does this hang without first printing?
#include <stdio.h>
void main() {
printf("hello world");
while (1) {}
}
Because you haven't flushed the standard output. Try fflush. Even better, for C++ use...
std::cout << "hello world" << std::endl;
Separately, you'd have a better chance of it flushing itself if you added a \n, but not all implementations follow the Standard when it comes to such things.
Call fflush(stdout); after printf.
This will force the stdout buffer to be flushed and printed.
I am new to Boost threading and I am stuck with how output is performed from multiple threads.
I have a simple boost::thread counting down from 9 to 1; the main thread waits and then prints "LiftOff..!!"
#include <iostream>
#include <boost/thread.hpp>
using namespace std;
struct callable {
void operator() ();
};
void callable::operator() () {
int i = 10;
while(--i > 0) {
cout << "#" << i << ", ";
boost::this_thread::yield();
}
cout.flush();
}
int main() {
callable x;
boost::thread myThread(x);
myThread.join();
cout << "LiftOff..!!" << endl;
return 0;
}
The problem is that I have to use an explicit "cout.flush()" statement in my thread to display the output. If I don't use flush(), I only get "LiftOff!!" as the output.
Could someone please advise why I need to use flush() explicitly?
This isn't specifically thread related as cout will buffer usually on a per thread basis and only output when the implementation decides to - so in the thread the output will only appear on a implementation specific basic - by calling flush you are forcing the buffers to be flushed.
This will vary across implementations - usually though it's after a certain amount of characters or when a new line is sent.
I've found that multiple threads writing too the same stream or file is mostly OK - providing that the output is performed as atomically as possible. It's not something that I'd recommend in a production environment though as it is too unpredictable.
This behaviour seems to depend on OS specific implementation of the cout stream. I guess that write operations on cout are buffered to some thread specific memory intermediatly in your case, and the flush() operation forces them being printed on the console. I guess this, since endl includes calling the flush() operation and the endl in your main function doesn't see your changes even after the thread has been joined.
BTW it would be a good idea to synchronize outputs to an ostream shared between threads anyway, otherwise you might see them intermigled. We do so for our logging classes which use a background thread to write the logging messages to the associated ostream.
Given the short length of your messages, there's no reason anything should appear without a flush. (Don't forget that std::endl is the equivalent of << '\n' << std::flush.)
I get the asked behaviour with and without flush (gcc 4.3.2 boost 1.47 Linux RH5)
I assume that your cygwin system chooses to implement several std::cout objects with associated std::streambuf. This I assume is implementation specific.
Since flush or endl only forces its buffer to flush onto its OS controlled output sequence the cout object of your thread remains buffered.
Sharing a reference of an ostream between the threads should solve the problem.
I have a Qt/C++ acpplication which is using a C++ library.
This library has a log mechanism that writes string messages to standard error.
Now, I would like to be able to redirect those messages toward a panel in my Qt tool.
I would like to avoid modifying the library because is adopted by many other clients.
Any idea how to get at runtime these messages?
Having instead the possibility of changing it what could be a good practise for carrying those messages up to the application?
That's very poor library design. However...
How does it write to standard error. If it is outputing to std::cerr,
then you can change the streambuf used by std::cerr, something like:
std::filebuf logStream;
if ( ~logStream.open( "logfile.txt" ) )
// Error handling...
std::streambuf* originalCErrStream = std::cerr.rdbuf();
std::cerr.rdbuf( &logStream );
// Processing here, with calls to library
std::cerr.rdbuf( originalCErrStream ); // Using RAII would be better.
Just don't forget to restore the original streambuf; leaving std::cerr
pointing to a filebuf which has been destructed is not a good idea.
If they're using FILE*, there's an freopen function in C (and by
inclusion in C++) that you can use.
If they're using system level output (write under Unix, WriteFile
under Windows), then you're going to have to use some system level code
to change the output. (open on the new file, close on fd
STDERR_FILENO, and dup2 to set STDERR_FILENO to use the newly
opened file under Unix. I'm not sure it's possible under
Windows—maybe something with ReOpenFile or some combination of
CloseHandle followed by CreateFile.)
EDIT:
I just noticed that you actually want to output to a Qt window. This
means that you probably need a string, rather than a file. If the
library is using std::cerr, you can use a std::stringbuf, instead of
a std::filebuf; you may, in fact, want to create your own streambuf,
to pick up calls to sync (which will normally be called after each
<< on std::cerr). If the library uses one of the other techniques,
the only thing I can think of is to periodically read the file, to see
if anything has been added. (I would use read() in Unix, ReadFile()
in Windows for this, in order to be sure of being able to distinguish a
read of zero bytes, due to nothing having been written since the last
read, and an error condition. FILE* and iostream functions treat a
read of zero bytes as end of file, and will not read further.)
write to stderr is actually a syscall:
write(2, "blahblah ...");
you can redirect file descriptor number 2 to anything (file, pipe, socket):
close(2); // close old stderr
int redirect_target = open(...); // open a file where you want to redirect to
// or use pipe, socket whatever you like
dup2(redirect_target, 2); // copy the redirect_target fd to fd number 2
close(redirect_target);
in your situation, you will need a pipe.
close(2);
int pipefd[2];
pipe2(pipefd);
dup2(pipefd[1], 2);
close(pipefd[1]);
then, everything write to stderr can be obtained by reading pipe[0]:
read(pipe[0], buffer, ...);
If they're using calls to std::cerr, you can redirect this to a std::ostringstream.
#include <iostream>
#include <sstream>
class cerr_redirector
{
public:
cerr_redirector(std::ostream& os)
:backup_(std::cerr.rdbuf())
,sbuf_(os.rdbuf())
{
std::cerr.rdbuf(sbuf_);
}
~cerr_redirector()
{
std::cerr.rdbuf(backup_);
}
private:
cerr_redirector();
cerr_redirector(const cerr_redirector& copy);
cerr_redirector& operator =(const cerr_redirector& assign);
std::streambuf* backup_;
std::streambuf* sbuf_;
};
You can capture the output using:
std::ostringstream os;
cerr_redirector red(os);
std::cerr << "This is written to the stream" << std::endl;
std::cout will be unaffected:
std::cout << "This is written to stdout" << std::endl;
So you can then test your capture is working:
std::cout << "and now: " << os.str() << std::endl;
Or just add the contents of os.str() to your Qt Window.
Demonstration at ideone.
Here I found a complete implemenation of what i needed...
Thanks everybody for the help! :)
Will loading a DLL dynamically reconcile its stderr to a main application? If so, then how...?