linux环境的熟悉与实践.docx

上传人:b****3 文档编号:10267329 上传时间:2023-05-24 格式:DOCX 页数:19 大小:1.24MB
下载 相关 举报
linux环境的熟悉与实践.docx_第1页
第1页 / 共19页
linux环境的熟悉与实践.docx_第2页
第2页 / 共19页
linux环境的熟悉与实践.docx_第3页
第3页 / 共19页
linux环境的熟悉与实践.docx_第4页
第4页 / 共19页
linux环境的熟悉与实践.docx_第5页
第5页 / 共19页
linux环境的熟悉与实践.docx_第6页
第6页 / 共19页
linux环境的熟悉与实践.docx_第7页
第7页 / 共19页
linux环境的熟悉与实践.docx_第8页
第8页 / 共19页
linux环境的熟悉与实践.docx_第9页
第9页 / 共19页
linux环境的熟悉与实践.docx_第10页
第10页 / 共19页
linux环境的熟悉与实践.docx_第11页
第11页 / 共19页
linux环境的熟悉与实践.docx_第12页
第12页 / 共19页
linux环境的熟悉与实践.docx_第13页
第13页 / 共19页
linux环境的熟悉与实践.docx_第14页
第14页 / 共19页
linux环境的熟悉与实践.docx_第15页
第15页 / 共19页
linux环境的熟悉与实践.docx_第16页
第16页 / 共19页
linux环境的熟悉与实践.docx_第17页
第17页 / 共19页
linux环境的熟悉与实践.docx_第18页
第18页 / 共19页
linux环境的熟悉与实践.docx_第19页
第19页 / 共19页
亲,该文档总共19页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

linux环境的熟悉与实践.docx

《linux环境的熟悉与实践.docx》由会员分享,可在线阅读,更多相关《linux环境的熟悉与实践.docx(19页珍藏版)》请在冰点文库上搜索。

linux环境的熟悉与实践.docx

linux环境的熟悉与实践

北京邮电大学操作系统实验实验报告

班号:

2008211316姓名:

张荣学号:

08211627

实验日期:

2010-11-30

实验名称:

linux环境的熟悉与实践

一、实验目的

通过实际上机安装、操作linux系统,初步了解操作系统的工作原理,熟悉在linux环境下基本命令行的用法,并完成一些基本算法的代码实现,加深对操作系统工作原理的认识和进程的理解,达到理论与实际相结合的目的。

二、实验内容

◆基本要求

◇了解并安装linux

◇熟悉linux的基本命令,如ls、who、wc、pwd、ps、pstree、top,cat,cd,chgrp,chmod,chown,comm,cmp,cp,rm,diff,mv,rmdir等,了解工作环境

◇比较fork()和clone()的功能,利用fork()生成子进程和clone()生成线程。

◇利用pthread库,通过其中的mutex来实现生产者和消费者问题。

◆提高要求

根据系统硬件(设备可参照WINDOWS下的说明,主要是对显示器的驱动),编译内核:

◇makeconfig

◇makebzImage

◇将新定制核加入到/boot目录下,并修改GRUB。

三、实验分析

◆安装linux系统,并配置环境,在Ubuntu软件中心安装常用的应用软件程序,例如输入法等基本系统支持程序。

◆linux相关命令的用法,可以借助互联网的使用来了解(linux下使用了MozillaFirefox浏览器),配以编程实现,就可以了解并掌握相关的基本命令。

◆操作系统书上介绍了用fork()来创建新的进程,新进程通过复制原来进程的地址空间而成。

但对于新进程来说,系统调用fork()的返回值为0,而对于父进程,返回值为子进程的标识符(非0)。

此外,在第四章的结尾介绍了clone()创建线程的功能,linux并不区分进程还是线程,事实上,Linux在讨论程序控制流时,通常称之为任务,而不是进程或者线程。

clone()被调用时,它被传递一组标记以决定父任务与子任务之间发生多少共享。

其中一些标志列举如下:

标志

含义

标志

含义

CLONE_FS

共享文件系统信息

CLONE_SIGHAND

共享信号处理程序

CLONE_VM

共享共同的内存空间

CLONE_FILES

共享打开的文件集

当调用系统调用fork()创建新的任务时,它具有父进程的所有数据的副本,当调用clone()时,也创建了新任务但并非复制所有的数据结构,根据传递给fork()的标志集,新的任务指向父任务的数据结构。

◆Pthread库中有很多现成的程序,使用的线程模型是POSIX线程接口,通常称为pthreads。

其中信号量mutex提供对缓冲池访问的互斥要求并初始化为1,信号量empty和full分别用来表示空缓冲项和满缓冲项的个数,信号量empty初始化为n,信号量full初始化为0。

full和empty实际上是一个指针,在循环队列里寻找适当的位置,进行生产消费动作。

四编程实现

◆Linux下常用命令的使用

1、ls-listdirectorycontents列出目录

2、who-showwhoisloggedon显示登录系统的用户信息

3、wc-printnewline,word,andbytecountsforeachfile打印行,字,数目

wc[OPTION]...[FILE]...

[OPTION]-l,printthenewlinecounts

-w,printthewordcounts

-c,printthebytecounts

4、pwd-printnameofcurrent/workingdirectory

5、ps-reportasnapshotofthecurrentprocesses

ps[options]

Toseeeveryprocessonthesystemusingstandardsyntax:

ps-e

Restricttheselectiontoonlyrunningprocesses:

psr

6、pstree-displayatreeofprocesses

top-displayLinuxtasks

cat-concatenatefilesandprintonthestandardoutput

7、cd[directory]-changethecurrentdirectory

8、chgrp-changegroupownership

chmod-changefilemodebits

chown-changefileownerandgroup

comm-comparetwosortedfileslinebyline

cmp-comparetwofilesbytebybyte

diff-comparefileslinebylinew

9、cp-copyfilesanddirectories

10、

rm-removefilesordirectories

mv-move(rename)files

rmdir-removeemptydirectories

◆fork()的实现

◇计算结果分析

这是课后作业的一道题的编程实现,由结果可以知道,子进程在建立的时候复制了父进程的数据,但子进程建立后,对于数据的存储空间和父进程时候不同的,在子进程中修改数据是不会影响到父进程中数据的值的,它们数据的存储空间不同。

故value=5。

而且改变wait函数的位置可以得到父进程执行到wait函数的地方开始等待子进程的结束,故先打印value=20后打印value=5。

程序总是先执行wait函数里的东西的,等待一个事件的发生。

◆Pthread()的实现

◆clone()的实现

◆生产者消费者的实现

五、提高要求的实现

◆升级内核和显卡驱动

升级前:

实验步骤:

一、下载内核源代码,用命令行实现

这次实验我升级的内核是linux-2.6.36.tar.bz2

安装有关编译程序

二、把内核包mv到/usr/src下,解压

cd到解压的目录下:

cdlinux-2.6.3

三、第一次编译无须清理,直接配置内核选项

默认直接点exit,就ok,如果要进行相应的细节设置也是可以的。

五、安装内核

然后可以修改menu.lst或者是grub.cfg,然后重启,到此内核升级成功

升级后:

注意:

内核自带的显卡驱动是受限的程序,下面我把他升级到官方的驱动程序:

因为每次升级内核后,都要重装nvidia驱动。

步骤:

下载显卡驱动,killgdm进程,进入字符界面,alt+F1进入命令行,登录用户。

下面默认设置,就ok了。

六、所遇到问题及实验感悟

1:

查阅相关资料得到:

Linux中生成线程方法:

第一种方式是用pthread库来实现的,是在用户程序本身中实现线程,这实际上是对线程的一种模拟,线程之间的切换和调度是在用户的进程内部进行的,这种方式就被称为用户空间的线程。

第二种方式是通过修改进程的实现方式来完成,可以使用不完全的进程创建方式创建共享数据空间的进程,在Linux下这种系统调用为clone()。

2:

当调用系统调用fork()创建新的任务时,它具有父进程的所有数据的副本,当调用clone()时,也创建了新任务但并非复制所有的数据结构,根据传递给fork()的标志集,新的任务指向父任务的数据结构。

3:

在用linux命令行操作的时候,要注意的一点就是你要知道你当前所在的目录,输入的命令在没有特殊指明的情况下,都是在当前目录操作的,一不小心,你就会发现你找不到目录的情况。

那就说明你需要用cd找到目录了。

4:

ls不加参数输出的是当前目录下的文件名,加参数,输出的是当前目录下文件夹内的子目录。

5:

diff判断的是文件夹内的文件目录是否相同。

6:

rm不能直接删除文件夹,如果文件夹内有目录的话,那样只能先一个一个删除文件夹里的东西,才可以删除空文件夹。

7:

在用fork创建进程的时候,用.c文件时,#include#include#includepid_tpid;pid=fork();

也可以用intpid,但是wait()的位置决定了子程序调用的位置,会对结果输出的顺序造成影响。

8:

pthread程序的编译和其他.c文件不同,例如,编译pthread.c文件,输入的命令行是gccpthread.c–pthread–opthread来实现,多一个–pthread,而且,编程验证,–pthread的位置比较灵活,可以在-o的前面,后面,甚至可以在pthread的后面。

9:

在用Pthread运行的过程中,sleep(10),后改为括号内是100,结果运行时间增加了好多,差点以为程序出错了,所以,具体的了解电脑的内部结构,譬如,时钟周期,可以帮自己在编程中处于有利的位置。

10:

升级内核和显卡驱动的时候,我选择了命令行,这是为了验证,在linux的操作平台上,许多命令是可以用命令行实现的,习惯了命令行,就可以摆脱对图形化界面的依赖,做出更多属于自己的东西。

此外,在linux环境下,安装程序,选择可以在linux的基础上运行的常用软件,在告别了傻瓜式安装的windows环境后,我突然发现了,原来操作系统这么神奇,有它自己的运行法则,也发现了自己的不足,恍然觉得,学计算机还是得用linux操作下,或从事下底层开发,才能真正的了解电脑。

七、附录:

源代码

◆fork()函数的实现

#include

#include

#include

intvalue=5;

intmain()

{

pid_tpid;

pid=fork();

if(pid==0)

{

value+=15;

printf("[son]\tvalue:

%d,pid:

%d\n",value,getpid());

}

elseif(pid>0)

{

//wait(NULL);

printf("[father]\tvalue:

%d,pid:

%d\n",value,getpid());

}

return0;

}

◆plthtead库实现线程

#include

#include

#include

intsum;

void*runner(void*param)

{

sleep(100);

sum=200;

printf("kugirl\n");

pthread_exit(0);

}

intmain(intargc,char*argv[])

{

pthread_ttid;

pthread_attr_tattr;

pthread_attr_init(&attr);

pthread_create(&tid,&attr,runner,argv[1]);

printf("\t\tsum=%d\t\t",sum);

pthread_join(tid,NULL);

printf("\t\tsum=%d\t\t",sum);

return0;

}

◆clone()函数的实现

#include"stdio.h"

#include"sched.h"

#include"signal.h"

#defineFIBER_STACK3000

inta;

void*stack;

intson()

{

printf("[son]\tvalue:

%d,pid:

%d\n",++a,getpid());

free(stack);

exit

(1);

}

intmain()

{

a=1;

stack=malloc(FIBER_STACK);

printf("sonthreadisbeingcreated!

!

\n");

clone(&son,(char*)stack+FIBER_STACK,CLONE_VM|CLONE_VFORK,0);

//CLONE_VM

//CLONE_VFORK

printf("[father]\tvalue:

%d,pid:

%d\n",a,getpid());

exit

(1);

}

◆生产者消费者的实现

#include

#include

#include

#include

#defineBUFFER_SIZE6

void*producer(void*param);

void*consumer(void*param);

intinsert_item(intitem);

intremove_item(int*item);

intpro_pointer=0;

intcon_pointer=0;

intbuffer[BUFFER_SIZE];

sem_tempty;

sem_tfull;

intmain()

{

sem_init(&empty,0,BUFFER_SIZE);

sem_init(&full,0,0);

pthread_ttid1,tid2;

pthread_attr_tattr1,attr2;

pthread_attr_init(&attr1);

pthread_attr_init(&attr2);

pthread_create(&tid1,&attr1,&producer,NULL);

pthread_create(&tid2,&attr2,&consumer,NULL);

pthread_join(tid1,NULL);

pthread_join(tid2,NULL);

printf("done!

");

return0;

}

void*producer(void*param)

{

pthread_mutex_tmutex;

pthread_mutex_init(&mutex,NULL);

while

(1)

{

srand((int)time(0)*3);

intrand1=rand()%5+1;

intrand_num=rand()%100;

sleep(rand1);

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_tmutex;

pthread_mutex_init(&mutex,NULL);

while

(1)

{

srand((int)time(0)*2);

intrand2=rand()%10+1;

sleep(rand2);

inthello;

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);

}

intinsert_item(intitem)

{

buffer[pro_pointer%(BUFFER_SIZE)]=item;

pro_pointer++;

return0;

}

intremove_item(int*item)

{

*item=buffer[con_pointer%BUFFER_SIZE];

con_pointer++;

return0;

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 政史地

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2