ImageVerifierCode 换一换
格式:DOCX , 页数:26 ,大小:32.64KB ,
资源ID:8152555      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/8152555.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(processlab.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

processlab.docx

1、processlab实验四 进程及进程管理4.1使用ps命令查看进程信息【实验内容】ps是基本的Linux命令,通过本实验,不仅要熟悉ps命令方法,更重要的是可以了解Linux进程的组成。【实验原理】ps:查看系统中的进程,Linux中可以使用ps -aux查看所有进程。其中PID代表进程ID,TTY是该进程是由哪个控制台启动的,CMD则是命令。 如果想列出更详细的信息,则可使用命令:“ps -auxw”。参数w表示加宽显示的命令行,参数w可以写多次,通常最多写3次,表示加宽3次,这足以显示很长的命令行了。【实验内容】在shell提示符下输入如下命令,并解释输出的结果:rootvm root#

2、psPID TTY TIME CMD 16767 pts/1 0:00 ps 18029 pts/1 0:00 bashrootvm root#ps auxPID TTY TIME CMD 4.2使用proc文件系统查看进程信息【实验目的】本实验将指导学员了解proc文件系统,通过proc文件系统查询进程信息,可以扩展到修改系统参数。【实验原理】/proc文件系统是一个虚拟文件系统,通过文件系统接口实现对内核的访问,输出系统运行状态。它以文件系统的形式,为操作系统本身和应用进程之间的通信提供了一个界面,使应用程序能够安全,方便的获得系统当前的运行状况和内核的内部数据信息,并且可以修改某些系统的

3、配置信息。【实验内容】1)认识proc文件系统的文件和目录rootvm root#cd /procrootvm root#ls2)通过proc文件系统查看系统当前进行状态rootvm root#cat /proc/self/status3)查询文件句柄的当前使用情况# cat /proc/sys/fs/file-nr426 15252458file-nr 文件显示了三个参数:分配的文件句柄总数、当前使用的文件句柄数以及可以分配的最大文件句柄数。如果需要增大 /proc/sys/fs/file-max 中的值,请确保正确设置 ulimit。对于 2.4.20,通常将其设置为 unlimited。

4、使用 ulimit 命令来验证 ulimit 设置: rootvm root# ulimitunlimited4)通过proc文件系统修改内核中预定的一些变量1)修改整个系统中文件句柄的最大数量rootvm root#ls /proc/sys/fs/file-max52458rootvm root#echo 65536 /proc/sys/fs/file-maxrootvm root#ls /proc/sys/fs/file-max655362)修改网络TTLrootvm root#ls /proc/sys/net/ ipv4/ip_default_ttl64rootvm root#echo

5、128 /proc/sys/net/ipv4/ip_default_ttlrootvm root#ls /proc/sys/net/ ipv4/ip_default_ttl1283)修改系统中最大进程数量rootvm root#ls /proc/sys/kernel/pid_max32768rootvm root#echo 65536 /proc/sys/kernel/pid_maxrootvm root#ls /proc/sys/kernel/pid_max655364)修改普通用户的最大RTC频率rootvm root#ls /proc/sys/dev/rtc/max-user-freq6

6、4rootvm root#echo 128 /proc/sys/dev/rtc/max-user-freqrootvm root#ls /proc/sys/dev/rtc/max-user-freq1285)其他一些信息rootvm root#cat /proc/cpuinfo - CPUrootvm root#cat /proc/interrupts - 中断 rootvm root#cat /proc/ioports - 设备IO端口 rootvm root#cat /proc/meminfo - 内存信息(i.e. mem used, free, swap size) rootvm ro

7、ot#cat /proc/partitions - 所有设备的所有分区 rootvm root#cat /proc/pci - PCI设备的信息 rootvm root#cat /proc/swaps - 所有Swap分区的信息 rootvm root#cat /proc/version - Linux的版本号4.3使用fork、exit和exec系统调用编写多进程程序【实验目的】本实验将通过编写fork等系统调用的程序,加深对系统进程及其控制的了解。【实验原理】fork后父子进程会同步运行,但父子进程的返回顺序是不确定的。设两个变量global和test来检测父子进程共享资源的情况。同时在进

8、程退出时对exit和_exit的区别进行测试和说明。【实验内容】1fork#include #include #include #include #include #include /#include int global=22;char buf=the test content!n;int main(void) int test=0,stat;pid_t pid;if(write(STDOUT_FILENO, buf, sizeof(buf) != sizeof(buf) perror(write error!); printf( fork test!n);/* fork */pid = f

9、ork(); /*we should check the error*/if (pid = -1) perror(fork); exit(0); else if (pid = 0) global+; test+; printf(global=%d test=%d Child,my PID is %dn,global,test,getpid(); exit(0);/*else be the parent*/ global+=2;test+=2;printf(global=%d test=%d Parent,my PID is %dn,global,test,getpid(); exit(0);/

10、printf(global=%d test=%d Parent,my PID is %d,global,test,getpid(); /_exit(0);编译执行,并分析结果: rootlocalhost root# ./testthe test content! fork test!global=23 test=1 Child,my PID is 2751global=24 test=2 Parent,my PID is 2750可以看出父子进程打印出了各自的进程号和对应变量的值,显然global和test在父子进程间是独立的,其各自的操作不会对对方的值有影响。将上述代码最后的两行代码替换为

11、注释掉的_exit(0)行,重新编译,查看结果,解释原因:rootlocalhost root# ./testthe test content! fork test!global=23 test=1 Child,my PID is 2771父进程的信息没有打印出来,其原因是:_exit()函数直接使进程停止运行,清除其使用的内存空间,并销毁其在内核中的各种数据结构;而exit()函数则在这些基础上作了一些包装,在执行退出之前加了若干道工序。exit()函数在调用exit系统调用之前要检查文件的打开情况,把文件缓冲区中的内容写回文件,即会 清理I/O缓冲。若将上述_exit(0)改为exit(0

12、),则肯定会有打印。另外,需要注意换行符n会引起IO的清理操作,若下面的语句printf(global=%d test%d Parent,my PID is %d,global,test,getpid(); 加上n,则调用_exit(0)的结果和调用exit(0)的结果是一样的。2vfork的特点将上述代码的pid = fork(); 改为pid = vfork();编译后运行结果如下:rootlocalhost root# ./testthe test content!fork test!global=23 test=1 Child,my PID is 2849global=25 test=

13、3 Parent,my PID is 2848 可以看出,vfork与fork区别在于共享的资源不一样,vfork调用后,子进程先对global和test加1,父进程运行时,在其基础之上再加2,得到上述运行结果。即vfork的特点是:在调用execv或者exit前子进程对变量的修改会影响到父进程,即他们是共享的;特别注意:父进程等待子进程调用execv或exit才继续执行。则若子进程依赖父进程的进一步动作时,父进程又必须阻塞到子进程调用execv或者exit才会往下执行,此时就会造成“死锁”。读者可自己设计测试一下这种“死锁”状态。4.4使用fork和exec系统调用编写执行命令的程序【实验目

14、的】本实验将通过编写fork和exec等系统调用的程序,加深对系统进程及其控制的了解。【实验原理】fork后调用exec族函数来调用系统命令或者程序来实现系统shell功能。【实验内容】execv函数族的使用注意点:调用execv后,程序不再返回!在上述代码基础上,在子进程的退出代码前加入如下代码:printf(global=%d test%d Child,my PID is %dn,global,test,getpid();if(execl(/bin/ps,ps,-au,NULL)0) perror(execl error!);printf(this message will never b

15、e printed!n);exit(0);编译运行后结果为:rootlocalhost root# ./testthe test content! fork test!global=23 test=1 Child,my PID is 2909USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMANDroot 2719 0.0 0.6 4360 1032 pts/1 S 23:14 0:00 /bin/bashroot 2908 0.0 0.1 1340 276 pts/1 R 23:38 0:00 ./testroot 2909 0.0 0.4

16、 2684 736 pts/1 R 23:38 0:00 ps -auglobal=25 test=3 Parent,my PID is 2908waitpid的作用是等待子进程退出并回收其资源,同时可以通过WIFEXITED等宏调用可以检测子进程退出的状态。在第一个示例fork使用的代码基础上进行修改,添加检测进程退出状态的子函数,参考代码如下:void exit_check(int stat) if (WIFEXITED(stat) printf(exit normally!the return code is: %d n,WEXITSTATUS(stat); else if (WIFSI

17、GNALED(stat) printf(exit abnormally!the signal code is: %d n,WTERMSIG(stat); 在父进程处理global和test变量前加入如下代码:if (waitpid(pid,&stat,0) = pid) exit_check(stat); / the status of exit check编译运行后结果为:rootlocalhost root# ./testthe test content! fork test!global=23 test=1 Child,my PID is 2973exit normally!the re

18、turn code is: 0global=24 test=2 Parent,my PID is 2972可以看出父进程回收了退出的子进程的资源,检测到了它的退出状态。4.5编写一个守护进程【实验目的】守护进程是Linux系统开发中很重要的知识点,本实验要求学员编写一个守护进程,通过本实验,学员可以熟悉守护进程的编写过程。【实验原理】 守护进程编写的主要步骤如下:1) 将程序进入后台执行。由于守护进程最终脱离控制终端,到后台去运行。方法是在进程中调用fork使父进程终止,让Daemon在子进程中后台执行。这就是常说的“脱壳”。子进程继续函数fork()的定义如下:pid_t fork(void

19、);2) 脱离控制终端、登录会话和进程组。开发人员如果要摆脱它们,不受它们的影响,一般使用 setsid() 设置新会话的领头进程,并与原来的登录会话和进程组脱离。3) 禁止进程重新打开控制终端。4) 重设文件权限掩码5) 关闭打开的文件描述符,并重定向标准输入、标准输出和标准错误输出的文件描述符。进程从创建它的父进程那里继承了打开的文件描述符。如果不关闭,将会浪费系统资源,引起无法预料的错误。关闭三者的代码如下:for (fd = 0, fdtablesize = getdtablesize(); fd fdtablesize; fd+)close(fd);6) 改变工作目录到根目录或特定目

20、录进程活动时,其工作目录所在的文件系统不能卸下【实验内容】守护进程实例包括两部分:主程序test.c和初始化程序init.c。主程序每隔一分钟向/tmp目录中的日志test.log报告运行状态。初始化程序中的init_daemon函数负责生成守护进程。读者可以利用init_daemon函数生成自己的守护进程。 1 init.c #include #include #include #include void init_daemon(void) int pid; int i; if (pid = fork() exit(0); /是父进程,结束父进程 else if (pid 0) exit(

21、-1 ); /fork失败,退出 setsid(); /第一子进程成为新的会话组长和进程组长 /并与控制终端分离 if (pid = fork() exit(0); /是第一子进程,结束第一子进程 else if (pid 0) exit(1); /fork失败,退出 /第二子进程不再是会话组长 for(i=0; i getdtablesize(); +i) /关闭打开的文件描述符 close(i); chdir(/tmp); /改变工作目录到 /tmp umask(0); /重设文件创建掩模 return; 2 test.c #include #include void init_daemo

22、n(void); /守护进程初始化函数 int main() FILE *fp; time_t t; init_daemon(); /初始化为Daemon while(1) /每隔2秒钟向test.log报告运行状态 sleep(2); /睡眠2秒钟 if(fp = fopen(test.log,a) != NULL) t=time(0); fprintf(fp,Im here at %sn,asctime(localtime(&t) ); fclose(fp); return 0;编译: rootvm root#gcc g o test init.c test.c 执行: rootvm ro

23、ot#./test 查看进程: rootvm root#ps ef 从输出可以发现test守护进程的各种特性满足上面的要求。实验五 进程间通信UNIX/LINUX系统的进程间通信机构(IPC)允许在进程间交换数据。本实验的目的是了解和熟悉LINUX支持的管道机制、信号机制、消息队列通信机制及共享存储区机制。5.1 无名管道通信实验【实验目的】1、了解什么是管道2、熟悉UNIX/LINUX支持的管道通信方式【实验内容】编写程序实现进程的管道通信。用系统调用pipe( )建立一管道,二个子进程P1和P2分别向管道各写一句话: Child 1 is sending a message! Child

24、2 is sending a message!父进程从管道中读出二个来自子进程的信息并显示(要求先接收P1,后P2)。参考程序#include #include int pid1, pid2;main( ) int fd2;char outpipe100, inpipe100;pipe(fd); /*创建一个管道*/while (pid1 = fork( ) = = -1);if (pid1 = = 0)lockf(fd1, 1, 0); sprintf(outpipe, child 1 process is sending message!); /*把串放入数组outpipe中*/ writ

25、e(fd1, outpipe, 50); /*向管道写长为50字节的串*/ sleep(5); /*自我阻塞5秒*/ lockf(fd1, 0, 0); exit(0); else while(pid2 = fork( ) = = -1); if (pid2 = = 0)lockf(fd1,1,0); /*互斥*/ sprintf(outpipe, child 2 process is sending message!); write(fd1, outpipe, 50); sleep(5); lockf(fd1, 0, 0); exit(0); else wait(NULL); /*同步*/

26、read(fd0, inpipe, 50); /*从管道中读长为50字节的串*/ printf(%s/n, inpipe); wait(NULL); read(fd0, inpipe, 50); printf(%s/n,inpipe); exit(0); 运行结果,延迟5秒后显示child 1 process is sending message!再延迟5秒child 2 process is sending message!5.2 有名管道通信实验【实验目的】1、掌握有名管道的创建和读写方式2、熟悉UNIX/LINUX支持的有名管道通信方式【实验内容】1. 创建有名管道2. 本进程执行循环等

27、待数据被写入到管道中并读有名管道3. 打开有名管道并写数据到名管道参考代码:/read_fifo.c#include #include #include #include #include #include #include #define BUFFER_SIZE 1024int main(int argc, char *argv) int fd; if (argc 2) fprintf(stdout, Usage: %s n, argv0); exit(1); /int open(const char *path, int oflag, .); if (fd = open(argv1, O_

28、RDONLY) 0) fprintf(stderr, open fifo %s for reading failed: %sn, argv1, strerror(errno); exit(1); fprintf(stdout, open fifo %s for reading successed.n, argv0); char bufferBUFFER_SIZE; ssize_t n; while (1) again: /ssize_t read(int fd, void *buf, size_t count); if (n = read(fd, buffer, BUFFER_SIZE) 0) if (errno = EINTR)

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1