题外话
此次实验在装有centOS
操作系统的远程服务器上进行,这里说说这里遇到的坑。
将写好的代码文件夹chap10_code
提交到远程服务器。在cmd
中输入scp -r 本地文件目录绝对路径 服务器用户名@服务器host:目标路径
现在让我们到服务器看下吧
可以看到文件已经传到服务器上了。然后就可以通过gcc
等命令运行了。
当然,由于代码已经在服务器上,我们也可以通过手机来操作运行代码,推荐移动端神器Termux
系统级I/O
输入/输出(I/O)
是在主存和外部设备(例如磁盘驱动器、终端和网络)之间复制数据的过程。
运行
ffiles1.c
#include "csapp.h"
int main(int argc, char *argv[])
{
int fd1, fd2, fd3;
char c1, c2, c3;
char *fname = argv[1];
fd1 = Open(fname, O_RDONLY, 0);
fd2 = Open(fname, O_RDONLY, 0);
fd3 = Open(fname, O_RDONLY, 0);
dup2(fd2, fd3);
Read(fd1, &c1, 1);
Read(fd2, &c2, 1);
Read(fd3, &c3, 1);
printf("c1 = %c, c2 = %c, c3 = %c\n", c1, c2, c3);
Close(fd1);
Close(fd2);
Close(fd3);
return 0;
}
abcde.txt
abcde
gcc -o ffiles1 ../ffiles1.c ../csapp.h ../csapp.c -lpthread
(注:我在chap10_code
目录下再创建了一个bin
目录用来存储所有的可执行文件。所以 .c
文件前要加上../
表示上级目录下的.c
文件)
运行结果:
ffiles2.c
#include "csapp.h"
int main(int argc, char *argv[])
{
int fd1;
int s = getpid() & 0x1;
char c1, c2;
char *fname = argv[1];
fd1 = Open(fname, O_RDONLY, 0);
Read(fd1, &c1, 1);
if (fork()) {
/* Parent */
sleep(s);
Read(fd1, &c2, 1);
printf("Parent: c1 = %c, c2 = %c\n", c1, c2);
} else {
/* Child */
sleep(1-s);
Read(fd1, &c2, 1);
printf("Child: c1 = %c, c2 = %c\n", c1, c2);
}
return 0;
}
运行gcc -o ffiles2 ffiles2.c csapp.h csapp.c -lpthread
命令 得到可以执行文件ffiles2
运行./ffiles2 ../abcde.txt
命令,可得到:
可以看到程序未退回bash
这是因为上述代码未关闭文件。应该在return 0
之前加上Close(fd1);
刚刚看了读文件,现在我们来看看写文件吧!
ffiles3.c
#include "csapp.h"
int main(int argc, char *argv[])
{
int fd1, fd2, fd3;
char *fname = argv[1];
fd1 = Open(fname, O_CREAT|O_TRUNC|O_RDWR, S_IRUSR|S_IWUSR);
Write(fd1, "pqrs", 4);
fd3 = Open(fname, O_APPEND|O_WRONLY, 0);
Write(fd3, "jklmn", 5);
fd2 = dup(fd1); /* Allocates new descriptor */
Write(fd2, "wxyz", 4);
Write(fd3, "ef", 2);
Close(fd1);
Close(fd2);
Close(fd3);
return 0;
}
运行gcc -o ffiles3 ffiles3.c csapp.h csapp.c -lpthread
得到 可执行文件ffiles3
运行./ffiles3 ../abcde.txt
然后用cat ../abcde.txt
查看abcde.txt
文件的内容
从图中可以看到fd3
的内容并未写入文件,这是因为在fd1
打开了文件并未关闭,系统对其上写锁,禁止其它的写入。