Define
1. Fully buffered means that I/O takes place only when the buffer is fully, the process explicitly calls fflush, or the process terminates by calling exit. A common size for the standard I/O buffer is 8192 bytes;
2. Line buffered means that I/O takes place when a newline is encountered, when the process calls fflush, or when the process terminates by calling exit.
3. Unbuffered means that I/O take place each time a standard I/O output function is called.
Most unix implementations of the standard I/O libarary use the following rules.
1. Standard error is always unbuffered.
2. Standard input and standard output are fully buffered, unless they refer to a terminal device, in which case, they are line buffered.
3. All other streams are fully buffered unless they refer to a terminal device,
in which case, they are line buffered.
Functions:
使用setbuf()和setvbuf()可以更改缓冲的类型:
setbuf(FILE *fp, char *buf) buf用malloc()开辟,当buf为NULL时,缓冲区为不带缓冲
setvbuf(FILE *fp,char *buf, int buf_mode, int size)
buf_mde有三种:_IOFBF 0 全缓冲, _IOLBF 1 行缓冲, _IONBF 2 不带缓冲
Default Buffering modes:
- stdin is always buffered
- stderr is always unbuffered
- if stdout is a terminal then buffering is automatically set to line buffered, else it is set to buffered
Default Buffer sizes:
- Buffer size only directly affects buffered mode
- The default size like the kernel is based on the page size (4096 bytes on my system)
- if stdin/stdout are connected to a terminal then default size = 1024; else size = 4096
Case 1 exit:
#include <stdio.h>
int main(int argc, char **argv)
{
printf("hello world!");
/*
_Exit(0);
_exit(0);
exit(0);
*/
}
case 2 line buffered:
#include <stdio.h>
int main(void)
{
int c;
do {
c = fgetc(stdin);
if (c == '\n') {
continue;
}
else if (c == 'z') {
break;
}
printf("--------\n");
printf("%c ", c);
/*
*/
/*
printf("%c\n", c);
*/
sleep(5);
} while (1);
return 0;
}
case 3.1 fork:
~/test
$ ./a.out
before fork!pid = 2312, flag = 6
before fork!pid = 2311, flag = 5
~/test
$ ./a.out > fork.log
~/test
$ cat fork.log
before fork!pid = 2314, flag = 6
before fork!pid = 2313, flag = 5
printf ("before fork!");
case 3.2 fully buffered:
~/test
$ ./a.out
before fork!
pid = 2372, flag = 6
pid = 2371, flag = 5
~/test
$ ./a.out > fullbuffer.log
~/test
$ cat fullbuffer.log
before fork!
pid = 2374, flag = 6
before fork!
pid = 2373, flag = 5
~/test
$
printf ("before fork!\n");
case 3.0 source code
#include <stdio.h>
int main(void)
{
/*
printf ("before fork!");
*/
printf ("before fork!\n");
int pid = 0;
int flag = 5;
pid = fork();
if (pid < 0) {
printf ("error\n");
}
else if (pid == 0) {
flag++;
}
else {
sleep(2);
}
printf("pid = %d, flag = %d\n", getpid(), flag);
return 0;
}