line buffering in stdio

Bob Lewis bobl at aeolus.UUCP
Sat Apr 27 06:44:26 AEST 1985


I just came across some rather interesting behavior in stdio that I think
deserves greater dissemination.  It isn't a bug, but it something that
people should be aware of.

Whenever you have a line-buffered output file, that means that stdio
flushes the buffer whenever (a) the buffer overflows or (b) you output a
newline.

The interesting behavior is in the putc(3S) macro in /usr/include/stdio.h
and in the function _flsbuf() that it calls.  With line buffering, _flsbuf
always resets the file's i/o buffer structure in such a way that putc will
call _flsbuf for every output character sent to it so that _flsbuf can
flush the buffer if that character is a newline.

This means that every time you use putc, it costs a function call.

In particular, note that standard out defaults to line buffering if it's a
tty.

One easy workaround is to disable line buffering.  You can do this by
installing your own buffer via setbuffer(3S), as shown in the program
below.  Interestingly, (in 4.2bsd at least) there is a function
setlinebuf(3S) to enable line buffering, but none to turn it off
explicitly.

A procedure call per character is not trivial.  The program below spends
about 10% of its (VAX 780, 4.2bsd) time in _flsbuf when compiled without
"-DFASTER".  Terminal I/O-bound programs should behave similarly.

	- Bob Lewis
	  ...!tektronix!teklds!bobl

----------------------- cut here ----------------------------
#include <stdio.h>

main()
{
	char buf[64];
	char outbuf[1024];
	int i, j;

#ifdef FASTER
	setbuffer(stdout, outbuf, sizeof(outbuf));
#endif
	for (j = 0; j < 64; j++) {
		for (i = 0; i < 63; i++)
			buf[i] = 'a' + (random() % 26);
		buf[63] = '\n';
		fwrite(buf, 1, 64, stdout);
#ifdef FASTER
		fflush(stdout);	/* be fair and do our own line flushing */
#endif
	}

	exit(0);
}



More information about the Comp.unix.wizards mailing list