- 前前言
- 前言
- 一、实验目的
- 二、实验工具与设备
- 三、实验预备知识
- 四、实验内容和步骤
- 四、实验代码及步骤截图
别问我为啥Linux没有实验四,我们老师只给了我们实验一、二、三、五、六、七。
我能怎么办啊,我一个强迫症我也难受啊QAQ。
为了帮助同学们完成痛苦的实验课程设计,本作者将其作出的实验结果及代码贴至CSDN中,供同学们学习参考。如有不足或描述不完善之处,敬请各位指出,欢迎各位的斧正!
一、实验目的- 学习Linux对文件系统的操作方法,掌握编程对文件进行操作的方法;
- 学习Linux下proc文件系统的特殊用途,学会利用其查看系统信息。
装有Linux系统的计算机
三、实验预备知识参阅教材中文件系统章节内容
四、实验内容和步骤一、Linux文件编程
- 从一个文件中读取最后10KB数据并复制到另一个文件,注意观察缓存大小OFFSET对运行效率的影响
#include#include #include #include #include #include #define BUFFER_SIZE 1024 #define SRC_FILE_NAME "src_file" #define DEST_FILE_NAME "dest_file" #define OFFSET 10240 int main() { int src_file,dest_file; unsigned char buff[BUFFER_SIZE]; int real_read_len; src_file = open(SRC_FILE_NAME,O_RDONLY); dest_file = open(DEST_FILE_NAME,O_WRONLY|O_CREAT,644); if(src_file < 0 || dest_file < 0) { printf("Open file error!n"); exit(1); } lseek(src_file,-OFFSET,SEEK_END); while((real_read_len = read(src_file,buff,sizeof(buff))) > 0) { write(dest_file,buff,real_read_len); } close(dest_file); close(src_file); return 0; }
- 编译、调试该程序使其能正常工作,运行之。解释这个程序的功能。
二、proc文件系统编程
-
/proc — 一个虚拟文件系统
/proc 文件系统是一种内核和内核模块用来向进程 (process) 发送信息的机制 (所以叫做 /proc)。这个伪文件系统让你可以和内核内部数据结构进行交互,获取有关进程的有用信息,在运行中改变设置。与其他文件系统不同,/proc 存在于内存之中而不是硬盘上。proc 文件系统可以被用于收集有用的关于系统和运行中的内核的信息。 -
下面是一些重要的文件:
/proc/cpuinfo - CPU 的信息 (型号, 家族, 缓存大小等)
/proc/meminfo - 物理内存、交换空间等的信息
/proc/mounts - 已加载的文件系统的列表
/proc/devices - 可用设备的列表
/proc/filesystems - 被支持的文件系统
/proc/modules - 已加载的模块
/proc/version - 内核版本
/proc/cmdline - 系统启动时输入的内核命令行参数
有一些以数字命名的目录,它们是进程目录。系统中当前运行的每一个进程在/proc下都对应一个以进程号为目录名的目录/proc/pid,它们是读取进程信息的接口。 -
通过 /proc 中可读写的文件提供了对内核的交互机制。写这些文件可以改变内核的状态。大部分 /proc 的文件是只读的,/proc/sys 目录存放所有可读写的文件的目录,可以被用于改变内核行为, /proc/sys/kernel 目录包含反通用内核行为的信息。
例如:
$ hostname machinename.domainname.com $ cat /proc/sys/kernel/hostname machinename $ echo "new-machinename" > /proc/sys/kernel/hostname $ hostname new-machinename.domainname.com
以上例子演示了如何修改本机的主机名。
- 使用C语言编写一个主机信息输出程序,使用open、close、read等系统调用读取不同的proc文件,获得主机信息,然后输出出来。
选作:利用write系统调用修改内核信息并验证。
三、使用fcntl函数实现文件锁
- 编写一个文件lock_set.c,该程序利用fcntl函数实现了一个lock_set函数,该函数实现文件锁功能,F_RDLCK为读锁,F_WRLCK为写锁,F_UNLCK为解锁。
int lock_set(int fd,int type)
{
struct flock old_lock,lock;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
lock.l_type = type;
lock.l_pid = -1;
fcntl(fd,F_GETLK,&lock);
if(lock.l_type != F_UNLCK)
{
if(lock.l_type == F_RDLCK)
printf("Read lock already set by %dn",lock.l_pid);
else if(lock.l_type == F_WRLCK)
printf("Write lock already set by %dn",lock.l_pid);
}
lock.l_type = type;
if((fcntl(fd,F_SETLKW,&lock)) < 0)
{
printf("Lock failed:type = %dn",lock.l_type);
return 1;
}
switch(lock.l_type)
{
case F_RDLCK:
printf("Read lock set by %dn",getpid());
break;
case F_WRLCK:
printf("Write lock set by %dn",getpid());
break;
case F_UNLCK:
printf("Release lock set by %dn",getpid());
return 1;
break;
default:
break;
}
return 0;
}
- 编写一个文件read_lock.c,该文件调用lock_set函数对文件hello上读锁。
#include#include #include #include #include #include #include "lock_set.c" int main(void) { int fd; fd = open("hello",O_RDWR|O_CREAT,0644); if(fd<0) { printf("Open file error.n"); exit(1); } lock_set(fd,F_RDLCK); getchar(); lock_set(fd,F_UNLCK); getchar(); close(fd); exit(0); }
- 编写一个文件write_lock.c,该文件调用lock_set函数对文件hello上写锁。
#include#include #include #include #include #include #include "lock_set.c" int main(void) { int fd; fd = open("hello",O_RDWR|O_CREAT,0644); if(fd<0) { printf("Open file error.n"); exit(1); } lock_set(fd,F_WRLCK); getchar(); lock_set(fd,F_UNLCK); getchar(); close(fd); exit(0); }
四、使用select函数实现多个文件的读写
- 编写如下程序,该程序利用select函数同时对文件in1、in2和标准输入文件进行读操作。当从标准输入文件读到字母q或Q时退出。
#include#include #include #include #include #include #define MAX_BUFFER_SIZE 1024 #define IN_FILES 3 #define TIME_DELAY 60 #define MAX(a,b) ((a>b)?(a):(b)) int main(void) { int fds[IN_FILES]; char buf[MAX_BUFFER_SIZE]; int i,res,real_read,maxfd; struct timeval tv; fd_set inset, tmp_inset; // fd set fds[0] = 0; if((fds[1] = open("in1", O_RDONLY|O_NONBLOCK)) < 0) { printf("Open in1 error.n"); return 1; } if((fds[2] = open("in2", O_RDONLY|O_NONBLOCK)) < 0) { printf("Open in2 error.n"); return 1; } maxfd = MAX(fds[1],fds[2]); FD_ZERO(&inset); // clear fd set for(i=0;i


