1、linux环境的熟悉与实践北京邮电大学 操作系统实验 实验报告班号:2008211316 姓名:张 荣 学号:08211627实验日期:2010-11-30 实验名称:linux环境的熟悉与实践一、实验目的通过实际上机安装、操作linux系统,初步了解操作系统的工作原理,熟悉在linux环境下基本命令行的用法,并完成一些基本算法的代码实现,加深对操作系统工作原理的认识和进程的理解,达到理论与实际相结合的目的。二、实验内容基本要求了解并安装linux熟悉linux的基本命令,如ls、who、wc、pwd、ps、pstree、top,cat,cd,chgrp,chmod,chown,comm,cm
2、p,cp,rm,diff,mv,rmdir等,了解工作环境比较fork()和clone()的功能,利用fork()生成子进程和clone()生成线程。利用pthread库,通过其中的mutex来实现生产者和消费者问题。提高要求根据系统硬件(设备可参照WINDOWS下的说明,主要是对显示器的驱动),编译内核:make configmake bzImage将新定制核加入到/boot目录下,并修改GRUB。三、实验分析安装linux系统,并配置环境,在Ubuntu软件中心安装常用的应用软件程序,例如输入法等基本系统支持程序。linux相关命令的用法,可以借助互联网的使用来了解(linux下使用了Mo
3、zilla Firefox 浏览器),配以编程实现,就可以了解并掌 握相关的基本命令。操作系统书上介绍了用fork()来创建新的进程,新进程通过复制原来进程的地址空间而成。但对于新进程来说,系统调用fork()的返回值为0,而对于父进程,返回值为子进程的标识符(非0)。此外,在第四章的结尾介绍了clone()创建线程的功能,linux并不区分进程还是线程,事实上,Linux在讨论程序控制流时,通常称之为任务,而不是进程或者线程。clone()被调用时,它被传递一组标记以决定父任务与子任务之间发生多少共享。其中一些标志列举如下:标志含义标志含义CLONE_FS共享文件系统信息CLONE_SIGH
4、AND共享信号处理程序CLONE_VM共享共同的内存空间CLONE_FILES共享打开的文件集当调用系统调用fork()创建新的任务时,它具有父进程的所有数据的副本,当调用clone()时,也创建了新任务但并非复制所有的数据结构,根据传递给fork()的标志集,新的任务指向父任务的数据结构。Pthread库中有很多现成的程序,使用的线程模型是 POSIX 线程接口,通常称为 pthreads。其中信号量mutex提供对缓冲池访问的互斥要求并初始化为1,信号量empty和full分别用来表示空缓冲项和满缓冲项的个数,信号量empty初始化为n,信号量full初始化为0。full和empty实际上
5、是一个指针,在循环队列里寻找适当的位置,进行生产消费动作。四编程实现Linux下常用命令的使用1、ls - list directory contents 列出目录2、who - show who is logged on 显示登录系统的用户信息3、wc - print newline, word, and byte counts for each file 打印行,字,数目wc OPTION. FILE. OPTION -l, print the newline counts -w, print the word counts -c, print the byte counts 4、pwd
6、- print name of current/working directory 5、ps - report a snapshot of the current processes ps options To see every process on the system using standard syntax: ps -e Restrict the selection to only running processes: ps r 6、pstree - display a tree of processes top - display Linux tasks cat - concate
7、nate files and print on the standard output 7、cd directory -change the current directory 8、chgrp - change group ownership chmod - change file mode bits chown - change file owner and group comm - compare two sorted files line by line cmp - compare two files byte by byte diff - compare files line by l
8、ine w9、cp - copy files and directories 10、 rm - remove files or directories mv - move (rename) files rmdir - remove empty directories fork()的实现计算结果分析这是课后作业的一道题的编程实现,由结果可以知道,子进程在建立的时候复制了父进程的数据,但子进程建立后,对于数据的存储空间和父进程时候不同的,在子进程中修改数据是不会影响到父进程中数据的值的,它们数据的存储空间不同。故value=5。而且改变wait函数的位置可以得到父进程执行到wait函数的地方开始等
9、待子进程的结束,故先打印value=20后打印value=5。程序总是先执行wait函数里的东西的,等待一个事件的发生。Pthread()的实现clone()的实现生产者消费者的实现五、提高要求的实现升级内核和显卡驱动升级前:实验步骤:一、下载内核源代码,用命令行实现这次实验我升级的内核是linux-2.6.36.tar.bz2 安装有关编译程序二、把内核包mv到/usr/src下,解压cd到解压的目录下:cd linux-2.6.3三、第一次编译无须清理,直接配置内核选项默认直接点exit,就ok,如果要进行相应的细节设置也是可以的。五、安装内核然后可以修改menu.lst 或者是grub.
10、cfg,然后重启,到此内核升级成功升级后:注意:内核自带的显卡驱动是受限的程序,下面我把他升级到官方的驱动程序:因为每次升级内核后,都要重装nvidia驱动。步骤:下载显卡驱动,kill gdm进程,进入字符界面,alt+F1 进入命令行,登录用户。下面默认设置,就ok了。六、所遇到问题及实验感悟1:查阅相关资料得到:Linux中生成线程方法:第一种方式是用pthread库来实现的,是在用户程序本身中实现线程,这实际上是对线程的一种模拟,线程之间的切换和调度是在用户的进程内部进行的,这种方式就被称为用户空间的线程。第二种方式是通过修改进程的实现方式来完成,可以使用不完全的进程创建方式创建共享数
11、据空间的进程,在Linux下这种系统调用为clone()。2:当调用系统调用fork()创建新的任务时,它具有父进程的所有数据的副本,当调用clone()时,也创建了新任务但并非复制所有的数据结构,根据传递给fork()的标志集,新的任务指向父任务的数据结构。3:在用linux命令行操作的时候,要注意的一点就是你要知道你当前所在的目录,输入的命令在没有特殊指明的情况下,都是在当前目录操作的,一不小心,你就会发现你找不到目录的情况。那就说明你需要用cd找到目录了。4:ls 不加参数输出的是当前目录下的文件名,加参数,输出的是当前目录下文件夹内的子目录。5:diff判断的是文件夹内的文件目录是否相
12、同。6:rm不能直接删除文件夹,如果文件夹内有目录的话,那样只能先一个一个删除文件夹里的东西,才可以删除空文件夹。7:在用fork创建进程的时候,用.c文件时,#include#include#includepid_t pid; pid=fork();也可以用int pid,但是wait()的位置决定了子程序调用的位置,会对结果输出的顺序造成影响。8:pthread 程序的编译和其他.c文件不同,例如,编译pthread.c文件,输入的命令行是gcc pthread.c pthread o pthread 来实现,多一个pthread,而且,编程验证,pthread的位置比较灵活,可以在-o的
13、前面,后面,甚至可以在pthread的后面。9:在用Pthread运行的过程中,sleep(10),后改为括号内是100,结果运行时间增加了好多,差点以为程序出错了,所以,具体的了解电脑的内部结构,譬如,时钟周期,可以帮自己在编程中处于有利的位置。10:升级内核和显卡驱动的时候,我选择了命令行,这是为了验证,在linux的操作平台上,许多命令是可以用命令行实现的,习惯了命令行,就可以摆脱对图形化界面的依赖,做出更多属于自己的东西。此外,在linux环境下,安装程序,选择可以在linux的基础上运行的常用软件,在告别了傻瓜式安装的windows环境后,我突然发现了,原来操作系统这么神奇,有它自己
14、的运行法则,也发现了自己的不足,恍然觉得,学计算机还是得用linux操作下,或从事下底层开发,才能真正的了解电脑。 七、附录:源代码fork()函数的实现#include#include#includeint value=5;int main()pid_t pid; pid=fork();if(pid=0) value+=15; printf(son tvalue:%d,pid:%dn,value,getpid(); else if (pid0) /wait(NULL); printf(father tvalue:%d,pid:%dn,value,getpid(); return 0;plth
15、tead库实现线程#include#include#includeint sum;void * runner(void * param) sleep(100); sum=200; printf(kugirln); pthread_exit(0);int main(int argc,char *argv) pthread_t tid; pthread_attr_t attr; pthread_attr_init(&attr); pthread_create(&tid,&attr,runner,argv1); printf(ttsum=%dtt,sum); pthread_join(tid,NUL
16、L); printf(ttsum=%dtt,sum);return 0;clone()函数的实现#include stdio.h#include sched.h#include signal.h#define FIBER_STACK 3000 int a;void *stack;int son() printf(son tvalue:%d,pid:%dn,+a,getpid(); free(stack); exit(1);int main() a=1; stack=malloc(FIBER_STACK); printf(son thread is being created!n); clone
17、(&son,(char *)stack+FIBER_STACK,CLONE_VM|CLONE_VFORK,0); /CLONE_VM /CLONE_VFORK printf(fathertvalue:%d,pid:%dn,a,getpid(); exit(1); 生产者消费者的实现#include #include #include #include #define BUFFER_SIZE 6 void *producer(void *param); void *consumer(void *param); int insert_item(int item); int remove_item(
18、int *item); int pro_pointer=0; int con_pointer=0; int bufferBUFFER_SIZE; sem_t empty; sem_t full; int main() sem_init(&empty,0,BUFFER_SIZE); sem_init(&full,0,0); pthread_t tid1,tid2; pthread_attr_t attr1,attr2; pthread_attr_init(&attr1); pthread_attr_init(&attr2); pthread_create(&tid1,&attr1,&produc
19、er,NULL); pthread_create(&tid2,&attr2,&consumer,NULL); pthread_join(tid1,NULL); pthread_join(tid2,NULL); printf(done!); return 0; void *producer(void *param) pthread_mutex_t mutex; pthread_mutex_init(&mutex,NULL); while(1) srand(int)time(0)*3); int rand1= rand()%5+1; int rand_num=rand()%100; sleep(r
20、and1); sem_wait(&empty); pthread_mutex_lock(&mutex); insert_item(rand_num); printf(producer:); printf(%d,rand_num); pthread_mutex_unlock(&mutex); sem_post(&full); printf(n); pthread_exit(0); void *consumer(void *param) pthread_mutex_t mutex; pthread_mutex_init(&mutex,NULL); while(1) srand(int)time(0
21、)*2); int rand2= rand()%10+1; sleep(rand2); int hello; sem_wait(&full); pthread_mutex_lock(&mutex); remove_item(&hello); printf(consumer:); printf(%d,hello); pthread_mutex_unlock(&mutex); sem_post(&empty); printf(n); pthread_exit(0); int insert_item(int item) bufferpro_pointer%(BUFFER_SIZE)=item; pro_pointer+; return 0; int remove_item(int *item) *item=buffercon_pointer%BUFFER_SIZE; con_pointer+; return 0;
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2