当前位置:文档之家› Linux复习(成熟期版)

Linux复习(成熟期版)

前面的可能考选择题,填空题,全部题型如下:一、选择题(10个题,每题2分,共20分)二、填空题(10个空,每空2分,共20分)三、程序阅读题(2道题,共20分)四、程序注释(1道题,共20分)可能考I/O五、编程题(1道题,共20分)P 154 文件I/O操作open()、read()、write()、lseek()和close()仔细阅读程序,能写注释或填空。

/* copy_file.c */#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <stdlib.h>#include <stdio.h>#define BUFFER_SIZE 1024/* 每次读写缓存大小1KB,关于《linux读写文件运行效率》的传送门*/#define SRC_FILE_NAME "src_file" /* 源文件名,之后用SRC_FILE_NAME代替src_file */#define DEST_FILE_NAME "dest_file" /* 目标文件名文件名,之后用DEST_FILE_NAME代替dest_file */ #define OFFSET 10240/* 复制的数据大小 1MB,也是lseek函数的偏移量*/int main(){int src_file, dest_file; //定义了2个变量unsigned char buff[BUFFER_SIZE]; //设定缓存的大小,定义为数组,存放读写缓存int real_read_len;/* 以只读方式打开源文件 */src_file = open(SRC_FILE_NAME, O_RDONLY); //前面的src_file是变量名,成功时为3,失败时为-1 //也可以写成src_file = open("src_file", O_RDONLY);/* 以只写方式打开目标文件,若此文件不存在则创建该文件, 访问权限值为644 */dest_file = open(DEST_FILE_NAME, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);//前面的dest_file是变量名,成功时为4,失败时为-1//也可以写成 d est_file = open("dest_file",O_WRONLY|O_CREAT,644);if (src_file < 0 || dest_file < 0) //打开文件失败时{printf("Open file error\n"); //输出这句话exit(1); // exit()中,1是返回给操作系统的,0是正常退出}/* 将源文件的读写指针移到最后10KB的起始位置*/lseek(src_file, -OFFSET, SEEK_END); //从文件的结尾处向前移动10KB// OFFSET 是偏移量,正值向前移,负值向后移。

这里在 OFFSET 前加了负号。

// SEEK_END 表示从文件的结尾开始。

//也可以写成lseek("src_file", -10240, SEEK_END);/* 读取源文件的最后10KB数据并写到目标文件中,每次读写1KB */while ((real_read_len = read(src_file, buff, sizeof(buff))) > 0)//读取成功时返回读到的字节数//红字部分也可以写成 read("src_file", buff, 1024){write(dest_file, buff, real_read_len);// real_read_len 在上一步被赋值为 1KB,即real_read_len = 1024;//也可以写成write("src_file", buff, 1024)close(dest_file); //关闭文件,这里等同于close(4);close(src_file); //关闭文件,这里等同于close(3);return 0; //main函数里,return 0 就是关闭程序。

子程序里 return 为返回值。

}P 214 子进程和父进程wait()和waitpid() 仔细阅读程序,能写注释或填空,写出输出结果。

wait()函数是用于使父进程阻塞,直到一个子进程结束或者该进程接到了一个指定的信号为止。

如果该父进程没有子进程或者他的子进程已经结束,则wait()就会立即返回。

本例中首先使用fork()创建一个子进程,然后让其子进程暂停5s(使用了sleep()函数)。

接下来对原有的父进程使用waitpid()函数,并使用参数WNOHANG 使该父进程不会阻塞。

若有子进程退出,则waitpid()返回子进程号;若没有子进程退出,则waitpid()返回0,并且父进程每隔一秒循环判断一次。

该程序源代码如下所示:/* waitpid.c */#include <sys/types.h>#include <sys/wait.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>int main(){pid_t pc, pr;pc = fork(); //使用fork()函数,创建了一个子进程,在子进程里pc = 0,在父进程里pc = 子进程的进程号。

//子进程和父进程是并行运行的,即同时运行。

//注意:是创建了一个子进程,不是一个子程序,也不是一个新程序。

程序只有一个。

if (pc < 0){printf("Error fork\n");else if (pc == 0) /*子进程*/ //pc=0是子进程,这段是子进程跑的程序。

{sleep(5); //子进程暂停5s/*子进程正常退出*/exit(0);}else /*父进程*/ //pc = 子进程的进程号 > 0,这段是父进程跑的程序。

{/*循环测试子进程是否退出*/do{/*调用waitpid,且父进程不阻塞*/pr = waitpid(pc, NULL, WNOHANG);//pc为子程序进程号。

//NULL是空,即不获取子进程退出时的状态。

//选项WNOHANG,当子进程没有退出时,返回0。

//所以子进程没退出时,pr =0 。

子进程退出时,pr = 子进程进程号。

/*若子进程还未退出,则父进程暂停1s*/if (pr == 0){printf("The child process has not exited\n"); //输出“子进程还未退出”。

sleep(1); //父进程暂停1s}} while (pr == 0); //子进程没退出时,pr =0。

一直做循环,直到 pr = 子进程进程号。

/*若发现子进程退出,打印出相应情况*/if (pr == pc) // pr = pc = 子进程进程号{printf("Get child exit code: %d\n",pr); //输出子进程的进程号}else{printf("Some error occured.\n");}}}将该程序交叉编译,下载到目标板后的运行结果如下所示:$./waitpidThe child process has not exitedThe child process has not exitedThe child process has not exitedThe child process has not exitedThe child process has not exitedGet child exit code: 75可见,该程序在经过5 次循环之后,捕获到了子进程的退出信号,具体的子进程号在不同的系统上会有所区别。

语句 waitpid(pc,NULL,0); 与 wait(NULL); 作用等价。

即 wait() 是 waitpid() 的一个特例。

P217 Linux 守护进程仔细阅读程序,能写注释或填空,写出输出结果。

1、守护进程,也就是通常所说的Daemon进程,是Linux 中的后台服务进程。

3、守护进程常常在系统引导载入时启动,在系统关闭时终止。

4、编写守护进程分5个步骤来创建一个简单的守护进程。

1.创建子进程,父进程退出pid = fork();if (pid > 0){exit(0); /*父进程退出*/}2.在子进程中创建新会话setsid(); //创建一个新的会话,并担任该会话组的组长。

//让进程摆脱原会话、原进程组、原控制终端的控制3.改变当前目录为根目录chdir("/"); //change direct 改变目录,简写为函数 chdir()4.重设文件权限掩码umask(0); //即把文件权限掩码设置为0,文件权限设置为 777 。

5.关闭文件描述符for(i = 0; i < MAXFILE; i++){close(i); // 关闭所有被父进程打开的文件。

关闭相应的文件描述符。

0、1、2默认打开。

//文件描述0为标准输入文件,1为标准输出文件,2为标准错误文件,从3开始为被打开文件。

}这样,一个简单的守护进程就建立起来了。

下面是实现守护进程的一个完整实例,该实例首先按照以上的创建流程建立了一个守护进程,然后让该守护进程每隔10s向日志文件/tmp/daemon.log写入一句话。

/* daemon.c 创建守护进程实例*/#include<stdio.h>#include<stdlib.h>#include<string.h>#include<fcntl.h>#include<sys/types.h>#include<unistd.h>#include<sys/wait.h>int main(){pid_t pid;int i, fd;char *buf = "This is a Daemon\n";pid = fork(); /* 第一步 */if (pid < 0){printf("Error fork\n");exit(1);}else if (pid > 0){exit(0); /* 父进程退出 */}chdir("/");/*第三步*/ //更改当前目录为根目录umask(0); /*第四步*/ //设置文件权限掩码为0for(i = 0; i <getdtablesize(); i++) /*第五步*/ //关闭所有被打开文件,通过关闭文件描述符的方式。

相关主题