操作系统-实验三-进程管理-实验报告|

| 浏览次数:

计算机与信息工程学院实验报告

姓名

学号

专业

软件工程

年级

2017级

课程

操作系统

主讲教师

党兰学

实验时间(年月日时)

2019年10月23日

实验地点

计算机学院201机房

辅导教师

党兰学

实验题目

进程管理

实验目的

加深对进程概念的理解,明确进程和程序的区别;

进一步认识并发执行的实质;

了解父进程和子进程之间的关系;

查看进程管理命令。

实验环境(硬件和软件)

硬件:PC机 软件:Oracle VM Virtualbox Linux

一、实验内容

1.练习在shell环境下编译执行程序

(注意: ①在vi编辑器中编写名为sample.c的c语言源程序

②用linux自带的编译器gcc编译程序,例如:gcc –o test sample.c

③编译后生成名为test.out的可执行文件;

④最后执行分析结果;命令为:./test)

注意:linux自带的编译程序gcc的语法是:gcc –o 目标程序名 源程序名,例如:gcc –o sample1 sample1.c,然后利用命令:./sample 来执行。如果仅用“gcc 源程序名”,将会把任何名字的源程序都编译成名为a.out的目标程序,这样新编译的程序会覆盖原来的程序,所以最好给每个源程序都起个新目标程序名。

2.进程的创建

仿照例子自己编写一段程序,使用系统调用fork()创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示“a”,子进程分别显示字符“b”和“c”。观察记录屏幕上的显示结果,并分析原因。

3.分析程序

实验内容要在给出的例子程序基础上,根据要求进行修改,对执行结果进行分析。二、实验步骤

1. 利用fork()创建一个小程序

编写程序

#include <sys/types.h>

main ()

{

int i=5;

pid_t pid;

pid=fork();

for(;i>0;i--)

{

if (pid < 0)

printf("error in fork!");

else if (pid == 0)

printf("i am the child process, my process id is %d and i=%d\n",getpid(),i);

else

printf("i am the parent process, my process id is %d and i=%d\n",getpid(),i);

}

for(i=5;i>0;i--)

{

if (pid < 0)

printf("error in fork!");

else if (pid == 0)

printf("the child process, my process id is %d and i=%d\n",getpid(),i);

else

printf("the parent process, my process id is %d and i=%d\n",getpid(),i);

}

}

运行程序

(3)分析程序

在这里,主程序先运行,在屏幕上输出一个a,之后两个子程序分别运行而输出c和b。

2 子进程对存取空间的复制

编写程序

(2)运行程序

分析程序

通过scanf(“%d”,&i);语句读取一个整数存在i,之后创建两个子程序,输入10后,子程序运行,之后经过一些读取赋值操作,输出i的值。

3 父子进程执行进程分析

编写程序

运行程序

程序分析

三次结果不同是因为printf(“In which process?\n”);所处位置经过变换,处于父子程序之后,父子程序之前和父程序之中。

4 修改程序验证父子进程关系

编写程序

文本代码:

#include <sys/types.h>

#include <unistd.h>

#include <signal.h>

#include <stdio.h>

#include <string.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#include <sys/sem.h>

#include <stdlib.h>

#define MY_SHMKEY // need to change

#define MY_SEMKEY // need to change

void sigend(int);

int shmid, semid;

int main(void)

{

int *shmptr, semval, local;

struct sembuf semopbuf;

if((shmid=shmget(MY_SHMKEY, sizeof(int), IPC_CREAT|IPC_EXCL|0666)) < 0)

{ /* shared memory exists, act as client */

shmid=shmget(MY_SHMKEY, sizeof(int), 0666);

semid=semget(MY_SEMKEY, 2, 0666);

shmptr=(int *)shmat(shmid, 0, 0);

printf("Act as producer. To end, input 0 when prompted.\n\n");

printf("Input a number:\n");

scanf("%d", &local);

while( local )

{

semopbuf.sem_num=0;

semopbuf.sem_op=-1;

semopbuf.sem_flg=SEM_UNDO;

semop(semid, &semopbuf, 1); /* P(S1) */

*shmptr = local;

semopbuf.sem_num=1;

semopbuf.sem_op=1;

semopbuf.sem_flg=SEM_UNDO;

semop(semid, &semopbuf, 1); /* V(S2) */

printf("Input a number:\n");

scanf("%d", &local);

}

}

else /* acts as server */

{

semid=semget(MY_SEMKEY, 2, IPC_CREAT|0666);

shmptr=(int *)shmat(shmid, 0, 0);

semval=1;

semctl(semid, 0, SETVAL, semval); /* set S1=1 */

semval=0;

semctl(semid, 1, SETVAL, semval); /* set S2=0 */

signal(SIGINT, sigend);

signal(SIGTERM, sigend);

printf("ACT CONSUMER!!! To end, try Ctrl+C or use kill.\n\n");

while(1)

{

semopbuf.sem_num=1;

semopbuf.sem_op=-1;

semopbuf.sem_flg=SEM_UNDO;

semop(semid, &semopbuf, 1); /* P(S2) */

printf("Shared memory set to %d\n", *shmptr);

semopbuf.sem_num=0;

semopbuf.sem_op=1;

semopbuf.sem_flg=SEM_UNDO;

semop(semid, &semopbuf, 1); /* V(S1) */

}

}

}

void sigend(int sig)

{

shmctl(shmid, IPC_RMID, 0);

semctl(semid, IPC_RMID, 0);

exit(0);

}

运行程序

分析程序

本示例主要体现进程间的直接制约关系,由于使用共享存储区,也存在间接制约关系。进程分为服务进程和客户进程,服务进程只有一个,作为消费者,在每次客户进程改变共享存储区内容时显示其数值。各客户进程作为生产者,如果共享存储区内容已经显示(被消费),可以接收用户从键盘输入的整数,放在共享存储区。

编译后执行,第一个进程实例将作为服务进程,提示:

ACT CONSUMER!!! To end, try Ctrl+C or use kill.

服务进程一直循环执行,直到用户按Ctrl+C终止执行,或使用kill命令杀死服务进程。

其他进程实例作为客户进程,提示:

Act as producer. To end, input 0 when prompted.

客户进程一直循环执行,直到用户输入0。

5 模拟临界资源访问的示例程序

编写程序

文本代码:

#include <sys/types.h>

#include <unistd.h>

#include <signal.h>

#include <stdio.h>

#include <string.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#include <stdlib.h>

#define MY_SHMKEY // need to change

#define MAX_BLOCK 1024

#define MAX_CMD 8

struct shmbuf {

int top;

int stack[MAX_BLOCK];

} *shmptr, local;

char cmdbuf[MAX_CMD];

int shmid, semid;

void sigend(int);

void relblock(void);

int getblock(void);

void showhelp(void);

void showlist(void);

void getcmdline(void);

int main(void)

{

if((shmid=shmget(MY_SHMKEY, sizeof(struct shmbuf), IPC_CREAT|IPC_EXCL|0666)) < 0)

{ /* shared memory exists, act as client */

shmid=shmget(MY_SHMKEY, sizeof(struct shmbuf), 0666);

shmptr=(struct shmbuf *)shmat(shmid, 0, 0);

local.top=-1;

showhelp();

getcmdline();

while(strcmp(cmdbuf,"end\n"))

{

if(!strcmp(cmdbuf,"get\n"))

getblock();

else if(!strcmp(cmdbuf,"rel\n"))

relblock();

else if(!strcmp(cmdbuf,"list\n"))

showlist();

else if(!strcmp(cmdbuf,"help\n"))

showhelp();

getcmdline();

}

}

else /* acts as server */

{

int i;

shmptr=(struct shmbuf *)shmat(shmid, 0, 0);

signal(SIGINT, sigend);

signal(SIGTERM, sigend);

printf("NO OTHER OPERATION but press Ctrl+C or use kill to end.\n");

shmptr->top=MAX_BLOCK-1;

for(i=0; i<MAX_BLOCK; i++)

shmptr->stack[i]=MAX_BLOCK-i;

sleep(1000000); /* cause sleep forever. */

}

}

void sigend(int sig)

{

shmctl(shmid, IPC_RMID, 0);

semctl(semid, IPC_RMID, 0);

exit(0);

}

void relblock(void)

{

if(local.top<0)

{

printf("No block to release!");

return;

}

shmptr->top++;

shmptr->stack[shmptr->top]=local.stack[local.top--];

}

int getblock(void)

{

if(shmptr->top<0)

{

printf("No free block to get!");

return;

}

local.stack[++local.top]=shmptr->stack[shmptr->top];

shmptr->top--;

}

void showhelp(void)

{

printf("\navailable COMMAND:\n\n");

printf("help\tlist this help\n");

printf("list\tlist all gotten block number\n");

printf("get\tget a new block\n");

printf("rel\trelease the last gotten block\n");

printf("end\texit this program\n");

}

void showlist(void)

{

int i;

printf("List all gotten block number:\n");

for(i=0; i<=local.top; i++)

printf("%d\t", local.stack[i]);

}

void getcmdline(void)

{

printf("\n?> ");

fgets(cmdbuf, MAX_CMD-1, stdin);

}

运行程序

程序分析

本示例的临界资源是一个建立在共享存储区的栈,由服务进程建立并初始化。初始状态下共享栈满,里面顺序放置一系列正整数(自栈顶向下:1,2,3...),代表空闲块号。客户进程利用共享栈进行数据块的分配和释放,以得到、归还一个块号代表,并不进行任何后续操作。程序中getblock过程从共享栈中弹出一个块号(分配),relblock过程把一个已分配块号压入共享栈(释放)。为简单起见,已分配块号在本地也使用栈结构保存,因而每次释放的是最后分配的块号。

编译后执行,第一个进程实例将作为服务进程,提示:

NO OTHER OPERATION but press Ctrl+C or use kill to end.

服务进程完成初始化后将进入睡眠状态,直到用户按Ctrl+C终止执行,或使用kill命令杀死服务进程。

其他进程实例作为客户进程,进入后首先有命令帮助提示,然后显示命令提示符“?> ”,在命令提示下可以使用的命令包括:

help 显示可用命令

list 列出所有已分配块号

get 分配一个新块

rel 释放最后分配块号

end 退出程序

三、实验数据记录

1.

2.

3.

4.

5.

四、问题讨论

(1)在程序运行过程中出现一个错误,错误语句:exit(0);

原因:少了一个头文件:#include <stdlib.h>

(2)心得体会:通过本次实验我了解了fork()函数等关于进程应用的函数并且学会了父子进程的各种基本操作,同时我也了解到做实验要谨慎加小心,一点差错就会导致全局崩溃。

相关热词搜索: 实验报告 实验 进程 操作系统 操作系统-实验三-进程管理-实验报告

【操作系统-实验三-进程管理-实验报告|】相关推荐

工作总结最新推荐

NEW
  • 入党积极分子竞选演讲稿优秀范文5篇入党积极分子竞选演讲稿优秀范文篇1尊敬的各位领导、老师、亲爱的同学们:大家好!室外寒风凛冽,而我心里却暖意融融。作为信

  • 学习《中国共产党员领导干部廉洁从政若干准则》心得体会精选4篇学习《中国共产党员领导干部廉洁从政若干准则》心得体会精选篇1学习了《中国共产党党员领导干部廉洁从

  • 六一儿童节学生作文400字优选3篇六一儿童节学生作文400字优选篇1六一儿童节,我们自己的节日。希望、焦虑不安、开心、兴奋都变成了大家脸部那灿烂的笑容,全部

  • 在学习贯彻党内主题教育精神读书班上的发言4篇在学习贯彻党内主题教育精神读书班上的发言篇1开展学习贯彻习近平新时代中国特色社会主义思想主题教育是一件事关全局的

  • 五年级小学生个人事迹篇4篇五年级小学生个人事迹篇篇1赵振炟,梁堂乡中心小学五年级二班的一名班干部,他品学兼优,性格开朗,乐于助人,善于思考,勤于探索,有较高

  • 弘扬五四精神学生作文精选10篇弘扬五四精神学生作文精选篇1岁月时光总是匆匆忙忙,转眼间我们迎来了五月美好的季节,而每年的五月四号里是我国历史上一次伟大的青少

  • 全面从严治党主体责任工作情况报告15篇全面从严治党主体责任工作情况报告篇120XX年以来,在县委、县政府的正确领导和县纪委的精心指导下,陈岱镇党委以落实全面

  • 2023食堂后勤人员总结幼儿园3篇2023食堂后勤人员总结幼儿园篇1转眼间,20__年在忙忙碌碌中悄悄离去了,回顾这一学期后勤工作的大事小事,我们在上级领导

  • 新时代中国特色社会主义思想主题教育个人学习体会3篇新时代中国特色社会主义思想主题教育个人学习体会篇1当前,学习贯彻习近平新时代中国特色社会主义思想主题教育正

  • 小学争做新时代好少年心得体会4篇小学争做新时代好少年心得体会篇1于歆玥热爱学习,与人为善、明礼诚信,连年荣获校级优秀班干部、优秀少先队员、最美大队委等荣誉称