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 = 6before fork!pid = 2311, flag = 5~/test$ ./a.out > fork.log~/test$ cat fork.log before fork!pid = 2314, flag = 6before fork!pid = 2313, flag = 5
printf ("before fork!");
case 3.2 fully buffered:
~/test$ ./a.out before fork!pid = 2372, flag = 6pid = 2371, flag = 5~/test$ ./a.out > fullbuffer.log~/test$ cat fullbuffer.log before fork!pid = 2374, flag = 6before 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;}