第一章 操作系统接口
1.1进程和内存
fork与exec
首先他们都是系统调用的接口
- fork在父进程中创建了一个子进程,并使用wait在父进程中等待子进程结束,回收。
fork返回值在子进程中为0,父进程中为子进程的pid
int pid=fork();
if (pid>0){
pid=wait((int*)0);//wait()函数参数的是一个地址,调用后参数是子进程的退出状态
}else if (pid==0){
exit(0);
}
- exec有两个参数,可执行文件的文件名与字符串参数数组
char* argv[3];
argv[0]="echo";
argv[1]="hello";
argv[2]=0;
exec("bin/echo",argv);
exec | fork | |
---|---|---|
内存内容是否相同 | 不同 | 相同 |
是否 |
是 | 否 |
1.2 I/O和文件描述符
文件描述符
文件描述符是一个强大的抽象,它在名称上指向文件,实际上可以指向任何I/O对象,即也可以指向设备和或者管道,在下面的描述中默认这一点。
write和read
read和write都是系统调用的接口,以字节为单位读取文件(通过文件描述符)。需要注意一点,buf本质上是指针,第二个参数需要传入指针。
write(fd,buf,n) //fd为文件描述符,
read(fd,buf,n)//buf为读或者写的字符串
-
引用文件的每个文件描述符都有一个与之关联的偏移量,且每次read和write都从此偏移量处开始读取或者写入。
-
每个进程都有一个文件描述符的私有空间,里面有三个从零开始的打开的文件描述符。进程从文件描述符0(标准输入input)读取,将输出写入文件描述符1(标准输出output),并将错误写入文件描述符2(标准错误)。
-
当文件没有更多的字节可读时,read返回0。读取或者写入正常的情况下,read和write返回读取或者写入的字节数。(说明这一条是为了理解下面这这一段代码)
char buf[512];
int n;
for(;;){
n=read(0,buf,sizeof(buf));
if (n==0){
break;
}
if (n<0){
fprintf(2,"read error");
exit(1);
}
if(write(1,buf,n)!=n){
fprintf(2,"write error");
exit(1);
}
}
close,open和dup
这三个都是关于文件和文件描述符的系统调用。
- close释放了一个文件描述符0,使其将来可以被open,dup,pipe重用。
close(0)