|
|
|
|
fflush(stdout) doesn't work as that returns before stdout has completed the flush. |
stdout
(or stderr
) stream, from where it eventually will be passed on to whatever the stdout
(or stderr
) stream happens to be connected to – might be a terminal, a file, or a pipe. Anyway, what happens with the output once it leaves your process, that is not under your control! If your stdout
is connected to a terminal, then it is totally up to the terminal process (on Windows that would be conhost.exe
) when and how it will show the output from your process, or how that output might be "interleaved" with outputs from another process – in cases where multiple processes are connected to the same terminal.fflush()
only flushes the internal buffer of the FILE*
stream, which means that all data that is still buffered inside your process will be sent to the destination (e.g. to the terminal, file or pipe) immediately. For example, if the FILE*
is connected to a "regular" file, then calling fflush()
only ensures that all pending data – from the FILE*
's internal buffer – is passed on to the OS (e.g. via write()
syscall), but you still have to call OS-specific function (e.g. fsync()
or _commit()
syscall) in order to ensure the data is actually written down to the disc as soon as possible. Similarly, if the FILE*
is connected to a terminal, then calling fflush()
only ensures that all pending data is passed on to the terminal process, but it can not ensure that the text is actually rendered to the screen by the terminal process immediately.ioPut()
is implemented, but if it calls WriteFile()
or WriteConsole()
– assuming that we are on Windows – then you simply pass by stdout
and all of the buffering that might be done by the underlying FILE*
. Still, the end result should be pretty much the same. After all, the FILE*
implementation on Windows is going to call WriteFile()
(or WriteConsole()
) in the end too...ioPut()
use threads?
Try _flushall() to flush the c stream under windows: |
FILE*
streams, so should make no difference (except greater overhead) to just fflush(stdout)
, when its explicitly the stdout
stream that you want to flush. But, either way, it only flushes the internal buffer of the FILE*
stream (see above).
Can you post some sample code that we can compile to demonstrate the problem? |
but if it calls WriteFile() or WriteConsole() |
Does the implementation of your ioPut() use threads? |
abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYS Foobar Foobar Foobar |
Fabcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYS oobar Foobar Foobar |
Yes. That's part of what ioInit() does. the display from our io is from a separate thread - which is probably the issue as WriteConsole() is not thread safe - that's why I need I probably need to wait for any existing output to complete - but how to know when done? |
WriteFile()
(or _write()
) and WriteConsole()
are thread safe – in the sense that you are allowed to call them from concurrent threads without synchronization and still nothing will break/crash. The crucial point is: There simply is no guarantee on how the data from concurrent WriteFile()
or WriteConsole()
invocations that go to the same file handle will be "multiplexed".FILE*
stream ultimately calls WriteFile()
or WriteConsole()
too – once its buffer is full or is flushed – but fwrite()
and friends use a lock (critical section) to synchronize those calls! That's why there is the non-synchronized version _fwrite_nolock()
.ioPut()
uses threads and it calls WriteFile()
or WriteConsole()
without explicit synchronization, then it kind of "defeats" the synchronization that is built into FILE*
streams, because your WriteFile()
will not be synchronized to the FILE*
stream's one.WriteFile()
or WriteConsole()
with the same lock (critical section) as the FILE*
stream uses internally. Problem is: The FILE
structure intentionally is opaque, i.e. you can not (easily) access its internal fields, such as the lock.
Well, WriteFile() (or _write()) and WriteConsole() are thread safe – in the sense that you are allowed to call them from concurrent threads without synchronization and still nothing will break/crash. The crucial point is: There simply is no guarantee on how the data from concurrent WriteFile() or WriteConsole() invocations that go to the same file handle will be "multiplexed". |
If your ioPut() uses threads and it calls WriteFile() or WriteConsole() without explicit synchronization, then it kind of "defeats" the synchronization that is built into FILE* streams, because your WriteFile() will not be synchronized to the FILE* stream's one. |
Yes - that's why I have to wait until FILE* streams is fully completed. The code currently accomplishes this by using a Sleep(50) (and has been for quite a while) but I don't like having an arbitrary Sleep() in the code - that's why I want to replace it with... - but I can't see an alternative... |
Sleep()
works at all - even if it happens to work most of the time.ioPut()
code, you synchronize every WriteFile()
or WriteConsole()
invocation on a CRITICAL_SECTION
, and if you also synchronize every access to stdout
or stderr
(including fflush()
) on that same CRITICAL_SECTION
, then it should work.
|
|
|
|
FILE*
streams and not use your "custom" I/O everywhere?