每学期都要讲授操作系统课程,于我,就是陈年旧饭,在一遍遍的翻炒中,能不烦么?怎么才能为之不烦?于学生,是一门抽象的无法触手可摸的云朵,仰望云端,但无法喊雨滴下来。
好在,操作系统是一座深厚的矿藏,你永远不敢宣称自己彻底了解它,充其量,我们只是遥望了一下这座山的四周。而各大公司都在挖掘这块宝藏。Google一边声称操作系统像隐身衣一样将消失在众人的视野中,一边有强悍的研发队伍,不断给免费的Linux 穿外衣。穿上虚拟机的Android俨然成了手机厂家追逐的明星,而借助于web的浓妆,依然搭乘Linux的便车,chrome OS就成了web界横空出世的大姐大了。在这些热闹的背后,我还得给学生从1+1讲起,什么是操作系统,什么是进程,什么是死锁等等,这使我从内心对蜡烛肃然起敬,但我是不甘心被燃烧成灰烬的,于是,希望学生们也能点燃起老师心中的希望。
什么是操作系统?操作系统能做什么?为什么每每我讲的兴趣盎然,可学生们交上来的报告,对操作系统的描述依然是书上文字的搬家?难道大量的输入信息,既没有在学生们的存储器中存放,也没有通过大脑CPU的加工,输出的仅是寥寥无几的空洞信息?
于是,还是以实例说明操作系统到底干什么,一段拷贝程序的片段呈现给大家:
inf=open(“/floppy/TEST”,O_RDONLY,0);
out=open(“/mydir/test”,O_WRONLY,0600);
do{
l=read(inf,buf,4096);
write(outf,buf,l);
} while(l);
close(outf);
close(inf);
然后通过说明这个程序的执行过程,阐述操作系统到底是如何参与的。实际上,这个执行过程足以写一本书,但在此,只能泛泛地说明,其中涉及的open, close,read,write的四个函数都讲离不开操作系统的参与。于是,建议学生,在不同操作系统下写出完整的程序,实现文件的拷贝。课后,一名同学发来他的程序:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <io.h>
int main(int argc,char *argv[])
{
int nReadHand; //只读文件句柄
int nWriteHand; //只写文件句柄
int nBytes; //从文件中读出字符的长度
char cBuf[10]; // 文件的存储数组
/*argv[1] = "copysource.txt";
argv[2] = "copydonate.txt";
*/
puts(argv[1]);
puts(argv[2]);
if((nReadHand =open(argv[1],O_RDONLY)) == -1) //打开要复制的文件,以只读方式打开
{
fprintf(stderr,"Read Error!/n");
exit(0);
}
if((nWriteHand =open(argv[2],O_CREAT)) == -1) //打开文件复制文件的的目标文件
{
fprintf(stderr,"Create Error!/n");
exit(0);
}
close(nWriteHand);
if((nWriteHand =open(argv[2],O_WRONLY)) == -1) //打开文件复制文件的的目标文件
{
fprintf(stderr,"Write Error!/n");
exit(0);
}
do
{
nBytes = read(nReadHand,cBuf,10); //读出一页的内容
write (nWriteHand,cBuf,nBytes);
}
while(nBytes);
close(nReadHand);
close(nWriteHand);
return 0;
}
者出现错误,那么原因何在?
学生让我给他看看这个程序到底有什么错误,我没有直接给出答案,而是回复如下:
“面对这样的问题,你是怎样思考的,这比问题本身还重要。
首先,分析一下自己的程序,程序有逻辑错吗?这么简单的程序,左找右找都找不出错误,那错误隐藏在何处?最大的可能就是给函数的参数有问题。
于是,你应当打开Linux文件系统编程的书,看一下open()函数参数的设置。当你创建一个新文件或者要写一个文件的时候,在Linux下,是否要涉及权限问题,你的程序在打开文件时传递这样的参数了吗?你通过main()函数参数传递的文件,其权限是否合适?如此思考,不仅仅是解决了一个问题,而是以后遇到同样的问题,你知道怎么去思考,从而一通多通。”