Linux基础实验目录实验一 (3)实验二 (4)实验三 (6)实验四 (9)实验五 (11)实验六 (14)实验七 (16)实验一螺旋矩阵一、实验目的1.熟悉linux下c程序编写。
2.掌握Makefile编写方法。
二、实验环境和工具Red Hat Linux三、实验流程1.编写螺旋矩阵程序2.编写Makefile文件四、实验结果五、实验心得通过这次实验,我熟悉了linux下c语言程序的编写,掌握了vi的一些常用操作,学会了使用gcc命令和makefile文件两种方法编译程序。
同时也使我熟悉了linux里常用命令的使用,还有,学会了挂载U盘的方法,可以很方便的往linux里传送文件。
六、关键代码Makefile 文件CC=gccEXEC=juzhenOBJS=juzhen.oall:$(EXEC)$(EXEC):$(OBJS)$(CC) -o $@ $(OBJS)clean:-rm -f $(EXEC) $(OBJS)实验二添加、删除用户一、实验目的1.设计一个shell程序,分组批量添加用户。
2.再设计一个批量删除用户的shell程序。
二、实验环境和工具Red Hat Linux三、实验流程1.编写shell程序2.修改文件权限chmod +x addusers3.运行脚本四、实验结果添加用户:删除用户:五、实验心得通过本次实验,我了解了shell脚本编程的方法和其语法规则。
掌握了使用shell脚本程序添加、删除用户的方法。
需要注意的是:shell脚本直接用vi编写,要特别注意空格。
六、关键代码添加用户:删除用户:实验三驱动螺旋矩阵一、实验目的1.掌握驱动模块的建立、插入和删除。
2.利用驱动模块实现测试程序输入矩阵的行和列,驱动程序生成相应的字母螺旋矩阵。
二、实验环境和工具Red Hat Linux三、实验流程1.编写驱动程序。
2.编写测试程序。
3.编写Makefile文件。
4.编译程序,插入驱动模块,运行驱动程序,观察运行结果,删除驱动模块,再次运行测试程序,观察运行结果。
四、实验结果1.插入驱动模块后测试程序运行结果:2.删除驱动模块后测试程序运行结果:五、实验心得通过这次实验,我对linux下驱动程序的工作原理有了一定的了解,认识了内核态和用户态的区别。
Linux以文件的形式定义系统的驱动程序,驱动程序不仅仅是内核的一部分,也是连接用户态和内核态之间的桥梁。
我学会了简单的驱动程序的开发和测试方法。
本次实验我遇到的难点有以下几点:1.实验要求输出一个字母螺旋矩阵,测试程序应当定义一位数组还是二维数组。
解决方法:使用一维数组,编程简单,在输出是将一维数组以二维形式输出即可。
2.驱动程序中如何实现螺旋矩阵。
解决方法:在驱动程序中另写一个螺旋矩阵函数,在ssize_t_evan_write函数里调用。
六、关键代码1.驱动程序:static char drv_buf[1024];static ssize_t evan_write(struct file *filp, char *buffer, size_t count){int row;int col;copy_from_user(drv_buf,buffer,count);row=(int)(drv_buf[0]);col=(int)(drv_buf[1]);printk("user write data to drivers!\n");solve(row,col);}3.测试程序:int main(){……printf("please input two integer:\n");scanf("%d%d",&row,&col);buf[0]=(char)(row);buf[1]=(char)(col);write(fd,buf,2);printf("Read %d bytes data from /dev/evan \n",row*col); read(fd,buf,row*col);showbuf(buf,row,col);ioctl(fd,1,NULL);close(fd);return 0;}void showbuf(char * buf,int row,int col){int i;for(i=0;i<row*col;i++){if(i!=0&&i%col==0){printf("\n");}printf("%4c",buf[i]);}printf("\n");}实验四哲学家进餐问题一、实验目的1.理解linux多线程机制。
2.使用多线程机制编程实现哲学家进餐模型,诠释死锁和避免死锁的办法。
二、实验环境和工具Red Hat Linux三、实验流程1.明确哲学家进餐问题。
2.编程实现。
3.编写Makefile文件。
4.运行调试。
四、实验结果五、实验心得通过本次实验,我了解了Linux下多线程机制,线程是系统能够独立调度和分配的最基本单位,可以理解为是进程基础上的进一步细化。
一个程序中同时运行多个线程来完成不同的任务,称之为多线程。
哲学家进餐问题是经典的同步问题,我先是去网上查找相关资料,找到了程序源码,一开始编译不通过,报告“段错误”,是因为代码中有些字符不规范,修改后编译通过。
经运行测试,程序中缺少延时机制,无法得出程序运行结果,我在程序里加了sleep语句后程序结果可读性大大改善。
从这个实验我也认识到培养在网上检索资料的能力的重要性。
六、关键代码注:加粗部分为修改部分sem_t chopsticks[PEOPLE_NUM];pthread_mutex_t mutex;void *philosopher(void *arg){int state = THINKING;int right = (id + 1) % PEOPLE_NUM;int left = (id + PEOPLE_NUM - 1) % PEOPLE_NUM;while(1){switch(state){case THINKING:sleep(1);……break;case HUNGRY:sleep(2);strcpy(ptrState,"Hungry");pthread_mutex_lock(&mutex);if(sem_wait(&chopsticks[left]) == 0){//非阻塞状态if(sem_wait(&chopsticks[right]) == 0){//非阻塞pthread_mutex_unlock(&mutex);state = EATING;}else{state = THINKING;sem_post(&chopsticks[left]);//释放请求的得到的left筷子 }}break;case EATING:sleep(3);sem_post(&chopsticks[left]);sem_post(&chopsticks[right]);……break;}}pthread_exit((void*)0);}int main(){pthread_t tid[PEOPLE_NUM];pthread_mutex_init(&mutex,NULL);for(i = 0 ; i < PEOPLE_NUM ; i ++){sem_init(&chopsticks[i],0,1);}for(i = 0 ; i < PEOPLE_NUM ; i ++){pthread_create(&tid[i],NULL,philosopher,(void*)i); ;创建五个哲学家线程}for(i = 0 ; i < PEOPLE_NUM ; i ++){pthread_join(tid[i],NULL); ;等待线程执行结束}return 0;}实验五 shell模拟程序的设计与实现一、实验目的1.理解shell的概念及其执行过程。
2.实现一个交互式shell,具备的功能至少有:打印提示符,获取用户输入指令;解析指令;寻找命令文件,执行指令。
二、实验环境和工具Red Hat Linux三、实验流程1.明确程序的功能要求。
2.逐步实现程序功能:打印提示符、获取用户输入命令、解析命令、寻找命令文件、执行命令。
代码见关键代码部分。
四、实验结果五、实验心得本次实验,让我学会了简单的shell模拟器的编程实现,理解了shell模拟器的工作原理和工作过程。
Shell是操作系统的用户界面,提供了用户与内核进行交互操作的接口,负责接收用户命令并把其送入内核去执行。
通过shell,用户可以方便的管理计算机资源。
Shell模拟器不断的接收用户指令并解析执行,直到用户关闭它,所以程序中要有一个while(1)循环。
实验中我只实现了对几个常用指令的解释执行,基本模拟了shell的实现。
我感觉本次试验的难点是:如何将用户输入的指令与系统中的指令正确对应;字符串操作不熟悉,一些函数不知道。
C语言提供了strncasecmp函数进行字符串比对,然后根据返回值进行相应的指令处理即可。
六、关键代码while(1) {path=get_current_dir_name();memset(cmd, 0, 1024);printf("@zhangyu %s>$ ",path);fgets(cmd, 1000, stdin);/*接受用户输入,命令最长1000个字符*/cmd[strlen(cmd) - 1] = 0;/*去掉输入的回车符*/b = transcmd(cmd);/*分析取得用户命令字*/switch(b){case 9:/*如果是Bye*/printf("See you later!\n");break;case 1:/*切换工作目录*/if(chdir(cmd + 3) != 0) {printf("chdir(%s) error!%s\n", cmd + 3, strerror(errno));}break;case 2:/*ls命令*/case 7:/*cp命令*/case 8:/*pwd命令*/system(cmd);break;case 3:/*pid命令*/printf("%d\n", getpid());break;case 4:/*rm命令*/remove(cmd + 3);break;case 5:/*mkdir命令*/mkdir(cmd + 6, 0755);break;case 6:/*mv命令*/p = strchr(cmd + 3, ' ');*p = 0;rename(cmd + 3, p + 1);break;case 0:/*不能识别的命令*/printf("Bad command, try again! All aviable commands are:\nlogout cd ls pwd pid rm mkdir mv cp\n", getpid());break;}}}char transcmd(char * s){if(!strncasecmp(s, "cd", 2)) return 1;else if(!strncasecmp(s, "ls", 2)) return 2;else if(!strncasecmp(s, "pid", 3)) return 3;else if(!strncasecmp(s, "rm", 2)) return 4;else if(!strncasecmp(s, "mkdir", 5)) return 5;else if(!strncasecmp(s, "mv", 2)) return 6;else if(!strncasecmp(s, "cp", 2)) return 7;else if(!strncasecmp(s, "pwd", 3)) return 8;else if(!strncasecmp(s, "bye",3)) return 9;else return 0;}实验六系统调用一、实验目的1.理解系统调用过程2.学会自己添加系统调用二、实验环境和工具Red Hat Linux三、实验流程1.决定系统调用名字,本实验中叫__NR_print_info,内核中系统调用实现程序的名字:sys_print_info。