实验一:熟悉Linux基础命令及进程管理
一、实验目的
(1)加深对进程概念的理解,明确进程和程序的区别。
(2)进一步认识并发执行的实质。
(3)分析进程争用资源的现象,学习解决进程互斥的方法。
二、实验内容
Liunx文件与目录操作
显示文件目录命令ls
改变当前目录命令cd
建立子目录mkdir
删除子目录命令rmdir
删除文件命令rm
文件改名命令mv
文件复制命令cp
显示文件的内容more或者less
查找文件find
重定向与管道 |
进程管理
运行以下附录部分中给出的程序,查看自己运行的结果,并进行分析。
1、写出程序的运行结果,并分析为什么会得到这样的结果。
2、画出程序执行的进程树并在相应的进程节点上标出进程号
编写程序,要求见附录部分
三、代码及运行结果分析
3.1 ls
3.2 cd
3.3 mkdir
3.4 rmdir
3.5 rm
3.6 mv
3.7 cp
3.8 find
3.9 重定向和管道符
进程管理
(1)程序一
(2)程序二
(3)程序三
(4)程序四
(5)自己编写一段程序,使用系统调用fork()创建子进程,认识进程的并发执行。
#include<stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
int main(){
pid_t pid;
pid=fork();
if(pid<0) /* 如果出错 */
printf("error occurred!\n");
else if(pid==0) /* 如果是子进程 */
{
printf("我是子进程1,进程号是%d\n",getpid());
pid_t pid1;
pid1 = fork();
if(pid1==0){
printf("我是子进程1的子进程,进程号是%d\n",getpid());
}
}
else{
printf("我是父进程,进程号是%d\n",getpid());
pid=fork();
if(pid==0)
printf("我是子进程2,进程号是%d\n",getpid());
else{
pid=fork();
if(pid==0)
printf("我是子进程3,进程号是%d\n",getpid());
}
}
return 0;
}
(6)修改程序四,进行加锁
#include<stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
int p1,p2,i;
while((p1=fork())==-1);
if(p1==0){
lockf(1,1,0);
for(i=0;i<50000; i++)
printf("son%d\n",i);
lockf(1,0,0);
}
else
{
while((p2=fork())==-1);
if(p2==0){
lockf(1,1,0);
for(i=0;i<50000;i++)
printf("daughter%d\n",i);
lockf(1,0,0);
}else{
lockf(1,1,0);
for(i=0;i<50000;i++)
printf("parent%d\n",i);
lockf(1,0,0);
}
}
return 0;
}
四、实验心得
(1)加深对进程概念的理解,明确进程和程序的区别。
(2)进一步认识并发执行的实质。
(3)分析进程争用资源的现象,学习解决进程互斥的方法。
(4)复习课本关于进程控制和进程同步的内容,加深对进程管理概念的理解。
(5)认真阅读实验材料中进程管理部分,分析多个进程的运行情况。
(6)对于进程间通信和并发矛盾的处理有了进一步的实践经验,关于并发加锁问题有了更加深入的理解。
(7)在进行并发编程的时候,一开始的加锁的位置并不对,所以一开始修改的结果虽然没有马上呈现出来,但是在多次运行以后还是发现了这个程序错误,从此得到的心得就是,针对并发编程,其测试用例必须是大量且多次进行的,否则一写微小的程序逻辑错误可能发现不出来,这样的程序一旦部署到生产环境无疑是十分危险的,所以对于并发编程必须设计非常完善的测试用例和使用高压力的测试环境。