文档库 最新最全的文档下载
当前位置:文档库 › 习题答案-Linux操作系统原理实践教程-崔继-清华大学出版社

习题答案-Linux操作系统原理实践教程-崔继-清华大学出版社

习题答案-Linux操作系统原理实践教程-崔继-清华大学出版社
习题答案-Linux操作系统原理实践教程-崔继-清华大学出版社

第1章

1、在VMwane中安装CentOS 7的基本步骤有哪些?

(1)新建虚拟机

(2)虚拟机设置

(3)启动虚拟机

(4)设置安装信息,包括软件选择,安装位置,分区等

(5)完成最后安装

2、安装Linux时可以设置哪些分区?有哪些分区是必须的?

能够设置的分区可以根据安装系统时提示,主要包括:/,/boot,swap,/home,/opt 等等;其中/(根)分区是必须的。

第2章

1、针对Linux 系统启动运行,有哪些运行目标?每个运行目标的含义是什么?

CentOS 从7.0 开始使用systemd 代替init 作为系统启动和服务器守护进程的管理器,负责在系统启动或运行时,激活系统资源,管理服务器进程。systemd 用目标(target)替代了运行级别的概念,提供了更大的灵活性,比如可以继承一个已有的目标,并添加其他服务来创建自己的目标。CentOS 7.0 之前的运行级别和systemd 目标之间的对应关系如下表所示。

2、Linux 有几种关机方法,每种关机操作有何异同?

关闭系统的命令有:

shutdown(最安全的方式),halt,init,telinit,poweroff,reboot,具体含义可以参考

帮助手册页。

第3章

more、less、cat、wc 命令有什么区别?

这几个命令可用于对文本文件的处理显示,主要区别在:more命令以分页(一次一屏)显示文本信息;less类似于more,但增加了回滚功能;cat本意是连接文件并在标准输出上输出,也就是将文件一次全部输出;wc用于统计输出文件中的行数、单词数、字节数等。

第4章

(1)发出命令显示行号。

底端命令方式下

:set nu

(2)保存到文件AboutLinux,并不退出。

底端命令方式下

:w AboutLinux

(3)删除一句“It is this kernel that forms the base around which a Linux operating system is developed.”。

在命令方式下,先把光标移到It处,再按d$。(从当前光标处到行末的所有字符删除)(4)查找单词“Finland”。

命令方式下输入/Finland,回车后会在第一个Finland处停下来。

(5)把第一段的“Finland”单词后的内容换行,使其变成三段内容。

插入方式下,将光标移到Finland后,按回车键即可。(vi的换行标志是回车符)

(6)将第二段的内容复制到文档的最后。

命令方式下:先用yy命令,然后移到文档最后,再按p键。

(7)删除第三段的内容。

命令方式下,光标移到第三段,用dd命令。(注,这里的段实际上是第3行。)

(8)恢复被删除的一段内容。

命令方式下,用u命令。

(9)查找所有的“Minix”单词,并全部改为“MINIX”。

底端命令方式下,:1,$s/Minix/MINIX/g

(10)不保存修改,退出vi。

底端命令方式下,:q!

(11)使用vi再次打开文件AboutLinux,在第二段后插入“He began his work in 1991 when he released version 0.02 and worked steadily until 1994 when version 1.0 of the Linux Kernel was released.”。

shell命令提示符下输入:vi AboutLinux(打开保存的文件)

可以使用命令::2快速移到指定的行(这里是第2段)使用A命令从当前行的最后一个字符开始编辑。

(12)保存并退出vi。

底端命令方式下,:wq

第5章

【任务1】查看和修改/root/ anaconda-ks.cfg文件的权限。

【任务2】用户和用户组权限设置验证

操作步骤:

1、创建用户组

group01,group02

参考命令:

groupadd group01

groupadd group02

2、创建用户并将用户加入组中

参考命令:

useradd –g group01 user1

useradd –g group01 user2

useradd –g group02 user3

passwd user1

passwd user2

passwd user3

3、使用帐户user1登录系统,在家目录/home/user1中新建文件a.txt,编辑文件的内

容(具体内容自定)。

可以使用vi创建文件a.txt,同时编辑内容。操作步骤如下:

(1)vi a.txt 进入vi编辑器

(2)按i键进入插入模式,自己编写一段内容。如下图所示。

(3)保存退出。

4、修改用户家目录/home/user1的权限,增加同组和其它人都可以读和执行权限。

注,修改权限的方式不唯一,可以是字符模式,也可以是数字模式,你可以选择你喜欢的任一种模式。下同。

5、用帐号user2,user3分别登录,测试文件a.txt是否可读、可写。

结果:user2可读,不可写;user3可读,不可写。如图,以user2登录为例:

使用vi编辑器编写文档a.txt时会提示该文件为只读文件。

6、切换到帐户user1,改变文件a.txt权限,使用户user2、user3对文件a.txt有读写权

限。

7、用帐号user2,user3分别登录系统,测试文件a.txt是否可读、可写。

user2和user3均对文件a.txt具有可读、可写权限。如图,以user2登录测试为例。

8、切换到root用户,修改文件a.txt的属主为user2。

第6章

1、使用ls命令查看文件:/bin/ls、/dev/sda、/dev/tty、/dev/stdin文件,完成表格6-1中的内容。

注:需要使用ls –l命令查看。

表6- 1 文件属性信息表

思考题:根据文件标识,分别说出这4个文件的类型。

-:普通文件

b:磁盘块文件

c:字符块文件

l:符号链接

2、使用df命令以便于阅读的方式查看文件系统磁盘空间使用情况,完成表格6-2中的内容。(可以添加行)

注:可以使用–h –T选项以显示表中的数据。

表6- 2 文件系统磁盘空间使用情况表

备注:这里填写的只是示例,填写内容以实际看见的数据情况为准。

3、使用命令xfs_info或xfs_growfs查看某个xfs文件系统信息,完成表格6-3中内容。

注:这里以/dev/sda1文件系统为例,使用命令xfs_info /boot可查看文件系统信息。

显示效果如下图所示。

表6- 3 查看xfs文件系统

备注:上述内容仅供参考,文件系统的大小不一,看到的结果不一。

4、使用命令xfs_admin或xfs_db查看某个xfs文件系统超级块信息,完成表格6-4的内容。

注:本处以查看/dev/sda2(“/”文件系统)为例。命令如下:

xfs_admin -f /dev/sda2

xfs_admin> sb 0

xfs_admin> print

表6- 4 查看超级块信息

5、使用命令stat查看文件/bin/ls的inode信息,完成表格6-5中的内容。

表6- 5 查看文件inode信息

6、按下列步骤完成链接文件的操作:

(1)在当前目录下创建文件myfile(提示:可用touch、vi等完成),文件的内容自定。(2)为myfile创建硬链接文件hmyfile。(提示:用ln命令完成)

(3)为myfile创建符号链接文件smyfile。(提示:用ln -s命令完成)

(4)使用stat命令查看文件myfile、hmyfile、smyfile,可以得出什么结论?

回答:

命令:ln myfile hmyfile创建硬链接

命令:ln -s myfile smyfile创建符号链接

如果使用ls –li命令查看,效果如下:

使用stat命令查看效果如下:

结论:

硬链接是给文件提供了另外一个入口,硬链接的文件只是文件名不同而已,文件的所有属性都相同。对其中任何一个文件的修改都会导致另外文件的修改。删除其中一个文件不会对另一个文件造成影响。

符号链接是给文件(源文件)创建另外一个打开路径(链接文件),通过不同的文件名打开相同的文件,两个文件的文件属性包括inode号码不同。如果删除源文件,将造成链接文件无法使用。

第7章

列举常用的Linux 文件与目录操作命令及用法实例,并上机完成目录创建、进入目录、建立文件、显示文件、显示目录、管道操作、输出重定向、文件合并、文件拆分、文件查找等功能(命令)。

第8章

【任务1】进程管理的基本命令使用练习

注,本答案中的截图均为示例图,效果显示可能不一致。

1、显示系统中所有进程的全部信息:输入命令 #ps –ef。

2、显示所有终端所有用户有关进程的所有信息:输入命令 #ps aux, 并记录其输出哪些信息。

3、查看进程树:#pstree

4、查看进程树同时显示进程号:#pstree -p

5、动态显示系统当前的进程和状态,每隔5秒的时间刷新一次:输入命令#top -d 5

6、在目录/tmp/test下用vi新建test.txt文件(如果目录/tmp/test不存在,则创建之),然后用kill将其终止。

a)输入命令#vi test.txt。

b)新建一个终端,输入命令#ps –ef查看vi的进程PID。

c)终止该进程,输入命令#kill ,如:kill 2305

d)输入命令#ps –ef,查看vi进程是否存在(类似于下图)。

输入命令:kill 1376后,vi进程应该不存在了。

7、查看进程bash当前的优先级值,并将其值下调5。

可以使用ps –l获取bash的PID号,如为1174;然后使用命令renice +5 1174调整。

【任务2】完成计划任务的设置

1、使用at命令执行一次性计划任务

在当天23点30分将/var/log中的内容打包备份,命名为log1.tar.gz。

at 23:30 today

tar –czf /root/log1.tar.gz /var/log

Ctrl+D(存盘退出)

效果如下图所示。

2、使用cron制定周期性计划任务

设置每周5晚23点30分执行日志备份,将/var/log中的内容打包备份,命名为log2.tar.gz。

使用命令:crontab –e,进入如下画面,填写如下记录,保存退出。

验证效果:(在指定的时间,指定的/root目录下生成的两个打包压缩文件测试效果图)

第9章

【任务1】阅读理解代码后,利用gcc编译程序。

命令:gcc rwbfile.c -o rwbfile

在磁盘的/root目录下,是否有文件“file1.bin”、“file2.bin”产生?如果有,它们的内容可以直接读取吗?

答:在/root目录下,会产生“file1.bin”、“file2.bin”两个文件,均为二进制文件,不可以直接读取。

4、修改读写缓存大小,使得一次可以读取256个字节。再次运行程序,查看运行结果。(贴图显示)

修改此处的值即可。

【任务2】

①:pid=fork()

②:getpid()

③:getpid()

问题:为什么程序输出内容中间会出现shell提示符?

原因:父进程只执行了3次,结束时会出现shell提示符。此时子进程尚没有结束(需要执行5次),所以子进程继续运行,在父进程结束处出现了子进程的运行提示信息,如图所示。

解决方法:可以在程序中添加让父进程等待子进程结束的语句。如下图代码所示:

测试运行结果类似如下图所示:

第10章

【任务1】上机测试程序。给出程序的功能及运行结果。

功能:此程序模仿ps程序的执行。父进程打印控制菜单并接收命令,创建子进程。子进程处理任务。此处模拟有两个功能:

命令:ps –a

命令:ps x

【任务2】

答案:

①:pid

②:"/bin/ps","ps","-a",NULL

③:NULL

【任务3】

#include

#include

#include

#include

#include

int main()

{

pid_t pid;

int n;

pid_t child_pid;

int exit_code;

pid=fork();

switch(pid)

{

case -1:

perror("fork failed!");

exit(EXIT_FAILURE);

break;

case 0:

n=5;

for(;n>0;n--){

printf("child process PID is %d.\n", getpid() );sleep(1);}

exit_code=88;/*此处值是随便写的,没有实际意义,下同。*/

break;

default:

n=3;

for(;n>0;n--){

printf("parent process PID is %d.\n", getpid() );sleep(1);}

exit_code=66;

}

/*父进程等待子进程完成*/

if(pid!=0)

{

child_pid=wait(&exit_code);

printf("child has finished: PID=%d\n",child_pid);

if(WIFEXITED(exit_code))

printf("child exited with code %d\n",WEXITSTATUS(exit_code));

else

printf("child terminated abnormally\n");

}

exit(exit_code);/*子进程终止时会用该函数将返回值带回给父进程*/ }

第11章

1、四个进程A、B、C、D都要读一个共享文件F,系统允许多个进程同时读文件F。但限制是进程A和进程C不能同时读文件F,进程B和进程D也不能同时读文件F。为了使这四个进程并发执行时能按系统要求使用文件,现用PV操作进行管理,请回答下面的问题:(1)应定义的信号量及初值:

(2)在下列的程序中填上适当的P、V操作,以保证它们能正确并发工作:

A() B() C() D()

{ { { {

[1]; [3]; [5]; [7];

read F; read F; read F; read F;

[2]; [4]; [6]; [8];

} } } }

解答:

(1)定义二个信号量S1、S2,初值均为1,即:S1=1,S2=1。其中进程A和C使用信号量S1,进程B和D使用信号量S2。

(2)从[1]到[8]分别为:P(S1) V(S1) P(S2) V(S2) P(S1) V(S1) P(S2) V(S2)

第12章

1、分析11.4.2中的程序的功能。并回答下面几个问题:

(1)使用wait函数的目的是什么?

(2)为什么要使用memset函数?

(3)查看父进程和子进程的ID各是多少?(提示:可以使用在后台执行程序,查看进程号)

解析:

(1)等待子进程结束后再继续运行。

(2)memset可以方便的清空一个结构类型的变量或数组。一般用来初始化,避免原来的数据影响当前运算的结果。

(3)可以通过进程查看器或者PS命令进行查看。

2、分析11.4.3中的程序,说明函数unlink的作用。

解析:用来删除通信完毕的管道文件,避免产生冗余文件,占用磁盘空间。

第13章

尝试使用发送与接收中的key值不一样或者设为0,看看是怎样的结果。分析一下原因。

解析:无法通信,利用IPC对象进行通信的进程必须通过key值获取同一个IPC对象的ID号后方可进行信息的发送和接受,如果不一致会导致无法通信。如果设置为0,则该IPC 对象仅用于私有通信,无法用来与其他外部进程进行通信。

第14章

1、一个信号量集中包含多个信号量结合共享内存如何实现进程间的同步和互斥。

解析:如果两个进程不仅需要同步,还要保证先后执行顺序,就要用两个信号量(互斥锁)来解决。如下案例为利用两个信号量进行同步和互斥的过程,可作为参考,然后在此基础上添加通信过程。

#include

#include

#include

#include

#include

#include

#include

#include

#define PROCESS_NR 4

void sigFunc(int signo)

{

int semId;

semId=semget(0x555,PROCESS_NR+1,IPC_CREAT|0600);

if(semId>0){

semctl(semId,0,IPC_RMID);

}

exit(1);

}

void p_lock(int idx,int semId);

void waitZero(int semId);

void doWork(int idx,int semId);

int main(void)

{

int semId,i;

pid_t pid;

////////////////////////////////

//对应的下标的信号量控制对应的子进程最后一个信号量控制父进程semId=semget(0x555,PROCESS_NR+1,IPC_CREAT|0600);

if(semId==-1)

{

perror("create sem");

return 11;

}

//init sem value

unsigned short vals[PROCESS_NR+1]={0};//对多个信号量值进行初始化if(semctl(semId,0,SETALL,vals)==-1)

{

perror("init sem val");

semctl(semId,0,IPC_RMID);

return 12;

}

////////////////////////////////

for(i=0;i

{

pid=fork();

if(pid==-1) return 1;

else if(pid==0)//child process

{

doWork(i,semId);//i标识进程的编号

exit(0);

}

}

//

signal(SIGINT,sigFunc);

//parent

struct sembuf bufs[PROCESS_NR+1]={0};

for(i=0;i

{

bufs[i].sem_num=i;

bufs[i].sem_op =1;

}

bufs[PROCESS_NR].sem_num=PROCESS_NR;//父亲的资源

bufs[PROCESS_NR].sem_op =PROCESS_NR;

////////////////////////////////////////

while(1)

{

waitZero(semId);

printf("========升起栅栏=======\n");

semop(semId,bufs,PROCESS_NR+1);

}

while(wait(NULL)!=-1)

;//empty

return 0;

}

void doWork(int idx,int semId)

{

pid_t pid=getpid();

int sec;

srand(pid);

while(1)

{

p_lock(idx,semId);

sec=rand()%10+1;

printf("%dth Do [%d] sec:%d\n",idx,pid,sec);

//随机休眠1-10s 模拟不同进程不同时侯做事情可能需要不同的时长

sleep(sec);

//通知父进程该子进程已执行完毕

p_lock(PROCESS_NR,semId);

}

}

////////////////////////////////////////

void p_lock(int idx,int semId)

{

struct sembuf buf={.sem_num=idx,.sem_op=-1};

semop(semId,&buf,1);

}

void waitZero(int semId)

{

struct sembuf buf={.sem_num=PROCESS_NR,.sem_op=0};

semop(semId,&buf,1);

}

2、如何把第二道程序拆分成两个文件,通过信号量集实现共享内存通信的进程同步和互斥。

解析:在发送方初始化信号量集,并创建共享内存发送数据,然后在接收方接入到对应的信号量集通过PV操作实现进程的同步和互斥,然后利用共享内存接收数据。

第15章

练习中提供的源程序只实现了一次通信过程,尝试一下改写,实现通信过程一直维持,直到按指定操作后才退出通信。

解析:发送方和接收方增加一个循环,循环结束条件均为同一指定操作即可。比如发送方在输入“end”后结束发送,接收方在接收到“end”后退出通信过程。

第16章

1、考虑一个有150个存储器单元的系统,如下分配给三个进程:

进程最大占有

1 70 45

2 60 40

3 60 15

使用银行家算法,以确定下面的任何一个请求是否安全:

(1)第4个进程到达,最多需要60个存储单元,最初需要25个单元;

(2)第4个进程到达,最多需要60个存储单元,最初需要35个单元;

如果安全,请给出任一安全序列;若不安全给出结果分配简表。

解析:

系统当前时刻进程状态表如上图所示,第4个进程请求25个单元,小于P4进程的need 和系统的Available值,可以进入试分配,试分配后如下图所示:

根据运算,可以得到安全序列:P1-P2-P3-P4。

系统当前时刻进程状态表如上图所示,第4个进程请求35个单元,小于P4进程的need

如图所示,试分配后的Available只有15,无法满足任意一进程的结束条件,进入不安全状态,本次试分配撤销,P4挂起等待。

2、操作系统分配资源时的一个主要考虑是避免死锁的发生。

若系统中有同类资源16个,有4个进程p1、p2、p3、p4共享该资源。

已知p1、p2、p3、p4所需的资源总数分别为8、5、9、6。

各进程请求资源的次序如表所示,若系统采用银行家算法为他们分配资源,那么____次申请分配会使系统进入不安全状态。

下表为进程申请资源的情况

序号进程申请量

1 P1 6

2 P2 4

3 P3 5

4 P4 1

5 P1 1

6 P2 1

供选择的答案

A.3、4

B.3、5

C.4、5

D.5、6

解析:C

第17章

填空答案:

(1)st.st_size;

(2)buffer;

第18章

1、对运行结果进行分析

相关文档