1.5输入和输出
1. 文件描述符
文件描述符通常是一个小的非负整数,内核用以标识一个特定进程正在访问的文件。当内核打开一个现有文件或创建一个新文件时,都返回一个文件描述符。在读写文件时,可以使用文件描述符。
2. 标准输入、标准输出和标准错误
每当运行一个新程序时,shell都会为其打开3个文件描述符,即标准输入、标准输出和标准错误,这三个描述符都链接到终端。
3. 不带缓冲的I/O
函数open、read、write、lseek、close提供了不带缓冲的I/O,这些函数都使用文件描述符。
Page7 实例
#include "apue.h"#define BUFFERSIZE 4096int main(void){ int n; char buf[BUFFERSIZE]; while((n = read(STDIN_FILENO, buf, BUFFERSIZE)) > 0) if(write(STDOUT_FILENO, buf, n) != n) err_sys("write error"); if (n < 0) err_sys("read error"); exit(0);}
说明:
- STDIN_FILENO和STDOUT_FILENO定义在unistd.h中,指定了标准输入和标准输出的文件描述符。
- read函数返回读取的字节数,此值用作要写的字节数。当到达输入文件末尾时,read返回0,程序停止。
调用方法:
- ./a.out > data
- ./a.out < infile > outfile
4. 标准I/O
标准I/O为不带缓冲的I/O函数提供了带缓冲的接口。
Page8 实例
#include "apue.h"int main(void){ int c; while((c = getc(stdin)) != EOF) if(putc(c, stdout) == EOF) // putc() returns EOF when error ocurrs err_sys("output error"); if(ferror(stdin)) err_sys("input error"); exit(0);}
1.6 程序和进程
1. 程序
程序是一个存储在磁盘上某个目录中的可执行文件,内核使用exec函数将程序度如内存,并执行程序。
2. 进程和进程ID
程序的执行实例被称为进程,每一个进程都有一个唯一的数字标识符,称为进程ID。进程ID是一个非负整数。
Page9 实例
#include "apue.h"int main(void){ printf("hello world from process ID %ld\n", (long)getpid()); exit(0);}
说明:使用getpid函数获取进程ID。
3. 进程控制
进程控制的函数主要有fork、exec、和waitpid。
Page9 实例
#include "apue.h"#include <sys/wait.h>int main(void){ char buf[MAXLINE]; pid_t pid; int status; printf("%% "); while(fgets(buf, MAXLINE, stdin) != NULL) { if(buf[strlen(buf) - 1] == '\n') buf[strlen (buf) - 1] = 0; if((pid = fork()) < 0) { err_sys("fork error"); } else if (pid == 0) { execlp(buf, buf, (char *)0); err_ret("couldn't execute: %s", buf); exit(127); } if((pid = waitpid(pid, &status, 0)) < 0) err_sys("waitpid error"); printf("%% "); } exit(0);}