s081[1]-操作系统原理

发布时间:2020-02-14 11:10:16 作者:jonson_jackson
来源:网络 阅读:255

操作系统

操作系统接口

前言

实验1需要我们调用unix操作系统保持出的接口,因此首先需要了解unix操作系统有关的知识。

操作系统(operating system)的功能

操作系统接口

int pid = fork();
if(pid > 0){
    printf("parent: child=%d\en", pid);
    pid = wait(0);
    printf("child %d is done\en", pid);
} else if(pid == 0){
    printf("child: exiting\en");
    exit(0);
} else {
    printf("fork error\en");
}

在下面的例子中,输出是:

也可能出现另外的情况,具体取决于父进程还是子进程首先进入其printf调用。

char *argv[3];
argv[0] = "echo";
argv[1] = "hello";
argv[2] = 0;
exec("/bin/echo", argv);
printf("exec error\en");

该片段将调用程序以程序/ bin / echo的实例替换,参数列表为echo hello。 大多数程序会忽略第一个参数,这通常是程序的名称

I/O 与文件描述符

* 文件描述符是一个小的整数,表示进程可以从中读取或写入的内核管理的对象。 进程可以通过打开文件,目录或设备,或通过创建管道,或通过复制现有描述符来获取文件描述符。 为简单起见,我们通常将文件描述符所指的对象称为“文件”; 文件描述符接口抽象了文件,管道和设备之间的差异,使它们看起来都像字节流。
* 在内部,xv6内核使用文件描述符作为每个进程表的索引,因此每个进程都有一个从零开始的文件描述符专用空间。 按照惯例,进程从文件描述符0(标准输入)读取,将输出写入文件描述符1(标准输出),并将错误消息写入文件描述符2(标准错误)。 就像我们将看到的那样,shell利用约定来实现I / O重定向(redirection)和管道(pipelines)。 shell确保始终打开三个文件描述符(user / sh.c:151),默认情况下,这三个文件描述符是控制台(console)的文件描述符。
char buf[512];
int n;
for(;;){
    n = read(0, buf, sizeof buf);
    if(n == 0)
    break;
    if(n < 0){
        fprintf(2, "read error\en");
        exit();
    }
    if(write(1, buf, n) != n){
        fprintf(2, "write error\en");
        exit();
    }
}

在代码片段中要注意的重要一点是cat不知道它是从文件,控制台还是管道中读取。 同样,cat不知道它是要打印到控制台,文件还是其他地方。 使用文件描述符以及文件描述符0是标准输入和输出文件描述符是标准输出的约定可以实现cat的简单实现。close系统调用将释放文件描述符,以供将来的open,pipe或dup系统调用重用。 新分配的文件描述符始终是当前进程中编号最小的未使用的描述符。

文件描述符和fork交互使I/O重定向易于实现。Fork会复制父文件的文件描述符表及其内存,以便子文件与父文件打开完全相同的文件。 exec系统调用替换了调用进程的内存,但保留了其文件表。 此行为允许Shell通过分叉,重新打开选定的文件描述符,然后exec新程序来实现I / O重定向。 这是shell为cat <input.txt命令运行的代码的简化版本:

char *argv[2];
    argv[0] = "cat";
    argv[1] = 0;
    if(fork() == 0) {
        close(0);
        open("input.txt", O_RDONLY);
        exec("cat", argv);
    }
if(fork() == 0) {
    write(1, "hello ", 6);
    exit(0);
} else {
    wait(0);
    write(1, "world\en", 6);
}
fd = dup(1);
write(1, "hello ", 6);
write(fd, "world\en", 6);

管道

int p[2];
char *argv[2];
argv[0] = "wc";
argv[1] = 0;
pipe(p);
if(fork() == 0) {
    close(0);
    dup(p[0]);
    close(p[0]);
    close(p[1]);
    exec("/bin/wc", argv);
} else {
    close(p[0]);
    write(p[1], "hello world\en", 12);
    close(p[1]);
}

* 程序调用pipe创建一个新管道,并将读取和写入文件描述符记录在数组p中。 在fork之后,父进程和子进程都具有引用管道的文件描述符。 子进程将读取端复制到文件描述符0上,关闭p中的文件描述符,然后执行wc。 当wc从其标准输入中读取时,它将从管道中读取。 父进程关闭管道的读取侧,写入管道,然后关闭写入侧。

文件系统

chdir("/a");
chdir("b");
open("c", O_RDONLY);

open("/a/b/c", O_RDONLY);
mkdir("/dir");
fd = open("/dir/file", O_CREATE|O_WRONLY);
close(fd);
mknod("/console", 1, 1);

Mknod在文件系统中创建一个文件,但是该文件没有内容。 但是,文件的元数据会将其标记为设备文件,并记录主设备号和次设备号(mknod的两个参数),它们唯一地标识内核设备。 当以后有一个进程打开文件时,内核会将read和write系统调用转换到内核设备的读写实现,而不是将它们转换到文件系统。

fstat系统调用得到有关文件描述符引用的对象的信息。此对象信息返回结构体stat,定义在
stat.h (kernel/stat.h):

#define T_DIR 1 // Directory
#define T_FILE 2 // File
#define T_DEVICE 3 // Device
struct stat {
    int dev; // File system’s disk device
    uint ino; // Inode number
    short type; // Type of file
    short nlink; // Number of links to file
    uint64 size; // Size of file in bytes
};

文件名与文件不同; 同一个文件(称为inode)可以具有多个名称(称为links)。
link系统调用将创建另一个文件名称,该名称引用与现有文件相同的inode。 下面的程序片段创建了一个名为a又为b的新文件。

open("a", O_CREATE|O_WRONLY);
link("a", "b");

读取,写入a与读取,写入到b相同。 每个inode由唯一的inode编号标识。 在上面的代码片段之后,可以通过检查fstat的结果确定a和b是否引用相同的文件:两者将返回相同的inode编号(ino),并且nlink将变为2。

unlink系统调用从文件系统中删除一个名称。 仅当文件的link计数为零且没有文件描述符引用该文件时, 才会将inode和其所在的磁盘空间清除。

因此当执行了

unlink("a");

之后,使用名称b任然能够访问文件。

下面的程序片段是一种惯用的方式创建一个临时inode。

fd = open("/tmp/xyz", O_CREATE|O_RDWR);
unlink("/tmp/xyz");

总结

Unix结合了文件描述符,管道和方便的shell语法以对其进行操作,这是编写通用可复用程序的重大进步。这是Unix的强大功能和广泛使用的原因,外壳程序是第一种所谓的“脚本语言”。Unixit系统调用接口在BSD,Linux,和Mac OSX 上广泛使用。

参考资料

dreamerjonson.com/2020/
pdos.csail.mit.edu/6.82
pdos.csail.mit.edu/6.82
pdos.csail.mit.edu/6.82


推荐阅读:
  1. DIX和DIF该诉你,什么叫端到端数据一致性
  2. Rman--基础命令

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

操作系统 08

上一篇:LVS负载均衡群集——keepalived+DR模式(实战!

下一篇:大型数据中心内部路由选择:为何选择BGP而不是OSPF

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》