实验2-进程的初步认识
更新时间:2023-10-13 15:52:01 阅读量: 综合文库 文档下载
- 实验一进程控制实验推荐度:
- 相关推荐
实验二:进程的初步认识实验
实验学时:2学时 一、
实验目的
(1) 掌握进程的概念
(2) 掌握系统调用
(3)设计程序,实现结果的不可再现性;使用同步原语,实现结果的可再现性 (4)设计程序,对系统的进程数目进行压力测试,对运行时间进行监控 二、实验基本原理 1.简单的系统调用
(1) fork();当fork()函数返回值为0时,子进程成功创建,以下为子进程作用域 头文件:
#include
#include
pid_t fork( void);
(pid_t 是一个宏定义,其实质是int 被定义在#include
返回值: 若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1
函数说明:
一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程(child process)。fork函数被调用一次但返回两次。两次返回的唯一区别是子进程中返回0值而父进程中返回子进程ID。
子进程是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本。注意,子进程持有的是上述存储空间的“副本”,这意味着父子进程间不共享这些存储空间。 linux将复制父进程的地址空间内容给子进程,因此,子进程有了独立的地址空间。
fork()在Linux系统中的返回值是没有NULL的. Error Codes
出错返回错误信息如下: EAGAIN
达到进程数上限.
ENOMEM
没有足够空间给一个新进程分配.
(2)syscall(SYS_getpid);调用系统函数syscall(),返回当前进程号 (3)getpid();调用系统函数getpid(),返回当前进程号 (4)getppid();获得父进程id号 (5)execl( );
头文件:#include
原型:int execl(const char *path, const char *arg, ...);
函数说明:execl()用来执行参数path字符串所代表的文件路径, 接下来的参数代表执行该文件时传递的argv[0],argv[1].....是后一个参数必须用空指针NULL作结束 返回值:成功则不返回值, 失败返回-1,失败原因存于errno中 2.linux的进程同步原语
(1)wait();
函数原型:
#include
进程一旦调用了wait就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程,wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。
参数status用来保存被收集进程退出时的一些状态,它是一个指向int类型的指针。但如果我们对这个子进程是如何死掉毫不在意,只想把这个僵尸进程消灭掉,(事实上绝大多数情况下,我们都会这样想),我们就可以设定这个参数为NULL,就像下面这样: pid = wait(NULL);
如果成功,wait会返回被收集的子进程的进程ID,如果调用进程没有子进程,调用就会失败,此时wait返回-1,同时errno被置为ECHILD。 (2)#include
#include
key_t ftok (char*pathname, char proj); 它返回与路径pathname相对应的一个键值。
(3)int semget(key_t key, int nsems, int semflg)
参数key是一个键值,由ftok获得,唯一标识一个信号灯集,用法与msgget()中的key相同;参数nsems指定打开或者新创建的信号灯集中将包含信号灯的数目;semflg参数是一些标志位。参数key和semflg的取值,以及何时打开已有信号灯集或者创建一个新的信号灯集与msgget()中的对应部分相同,不再祥述。该调用返回与健值key相对应的信号灯集描述字。调用返回:成功返回信号灯集描述字,否则返回-1。
注:如果key所代表的信号灯已经存在,且semget指定了IPC_CREAT|IPC_EXCL标志,那么即使参数nsems与原来信号灯的数目不等,返回的也是EEXIST错误;如果semget只指定了IPC_CREAT标志,那么参数nsems必须与原来的值一致,在后面程序实例中还要进一步说明。 (4)int semop(int semid, struct sembuf *sops, unsigned nsops);
semid是信号灯集ID,sops指向数组的每一个sembuf结构都刻画一个在特定信号灯上的操作。nsops为sops指向数组的大小。
(5)int semctl(int semid,int semnum,int cmd,union semun arg)
该系统调用实现对信号灯的各种控制操作,参数semid指定信号灯集,参数cmd指定具体的操作类型;参数semnum指定对哪个信号灯操作,只对几个特殊的cmd操作有意义;arg用于设置或返回信号灯信息。
该系统调用详细信息请参见其手册页,这里只给出参数cmd所能指定的操作。 IPC_STAT 获取信号灯信息,信息由arg.buf返回; IPC_SET
设置信号灯信息,待设置信息保存在arg.buf中(在manpage中给出了可以设置哪些信息);
GETALL 返回所有信号灯的值,结果保存在arg.array中,参数sennum被忽略; GETNCNT
返回等待semnum所代表信号灯的值增加的进程数,相当于目前有多少进程在等待semnum代表的信号灯所代表的共享资源;
GETPID 返回最后一个对semnum所代表信号灯执行semop操作的进程ID; GETVAL 返回semnum所代表信号灯的值;
GETZCNT 返回等待semnum所代表信号灯的值变成0的进程数; SETALL
通过arg.array更新所有信号灯的值;同时,更新与本信号集相关的semid_ds结构的sem_ctime成员;
SETVAL 设置semnum所代表信号灯的值为arg.val;
二、
参考程序
0. 创建进程示例 示例代码:
#include
int main(int argc, char ** argv ) {
int pid = fork(); if (pid < 0) {
printf(\ }
else if( pid == 0 ) {
printf(\ } else{
printf(\ } return 0; }
1.程序的不可再现性: $cat tc_print.c #include
int main(int argc,char *argv[]) {
printf(\ sleep(3);
printf(\
return(0); }
$cat ecp1.c
#include
int *status;
char *f=\要执行的程序名*/
char *argv1[3],*argv2[3],*argv3[3],*argv4[3]; /*执行程序所需的参数*/ argv1[0]=\ argv1[1]=\
argv1[2]=0; /*参数结束的标志*/
argv2[0]=\ argv2[1]=\ argv2[2]=0;
argv3[0]=\ argv3[1]=\ argv3[2]=0;
argv4[0]=\ argv4[1]=\ argv4[2]=0;
if(fork()==0) /*创建进程*/ {
execvp(f,argv1); /*执行程序*/ sleep(1);
execvp(f,argv2); sleep(1); } else {
if(fork()==0) /*创建进程*/ {
execvp(f,argv3); sleep(1);
}
else
{ wait(status); execvp(f,argv3);
sleep(1); } }
printf(\}
2. 实现程序结果的可再现性
(1)用wait()函数实现程序可再现性
#include
int status; //改动地点 void pp() {
n++;
if(n>=10)return;
wait(&status); //改动地点 wait系统调用会使父进程阻塞直到一个子进程结束 if(fork()==0) {
printf(\
for(n=0;n<1000000;n++) ; }
else pp(); }
int main() {
int i;
for(i=0;i<3;i++) { pp();
printf(\ } return 0; }
(2)用信号量semget()、semctl()、semop()实现进程同步 #include
#define SEMKEY (key_t)0x200
typedef union _senum{ int val;
struct semid_ds *buf; ushort *array; }semun;
static int semid;
struct sembuf p1={0,-1,0};//第一个是索引量,第二个-1是p操作,1是v操作。 struct sembuf v1={0,1,0};
int initsem() /*信号量初始化*/ {
semun x;
x.val=0; //用于付信号量初值
if((semid=semget(SEMKEY,1,0600|IPC_CREAT|IPC_EXCL))==-1)//创建信号量集,1为信号量集的中信号的个数
//1为信号量集中信号量个数 {
if(errno==EEXIST) //已经存在,则获得ID号. semid=semget(SEMKEY,1,0); }
if(semctl(semid,0,SETVAL,x)==-1) 0索引号, 设置初值,x为初值 {
perror(\ return(-1); }
return(semid); }
main() /*主操作*/ {
int i=0,semid; int j;
semid=initsem(); if(fork()==0) {
semop(semid,&p1,1);/*p操作*/ for(j=0;j<1000;j++) {
printf(\ sleep(1); }
printf(\ } else
{
if(fork()==0) {
for(i=0;i<1000;i++) {
printf(\ sleep(1); }
printf(\ semop(semid,&v1,1); } } }
3.创建进可能多的进程,得到这个数目的极限,进程启动后可以进入死循环 #include
#define MAXPRO 50 //此处定义估计最大的进程数,可以设为很大 #define SELLP 10000 int main(void) {
long max=0;
pid_t pid,pids[MAXPRO+1]; long i,l=0;
for (max=1;max pid=fork(); //不断创建进程 if (pid<0) break; else if (pid>0) { printf(\ pids[max]=pid; } else { while(1) { l++; //进入死循环 } } } for (i=1;i { if(kill(pids[i],SIGKILL)<0) //程序结束时将所有创建的进程强制关闭 { printf(\ } else printf(\} printf(\输出最大值 return 1; } (3)递归创建200个进程,记录总体创建的起始时间和结束时间,最后求创建单个线程的平均时间 #include #define MAXPRO 200 //创建200个进程 #define SELLP 10000 #define TESTTIME 10 long max=0,l=0; void myfork() //递归函数 { pid_t pid; int status; //if (max>=MAXPRO) exit(1); max++; pid=fork(); //递归创建进程 if (pid<0) exit(1); if (pid>0) { waitpid(pid,&status,0); //等待子进程结束 if (max<2) return; exit(1); } if (pid==0) { if (max>=MAXPRO) exit(1); myfork(); exit(1); } } int main(void) { long ave=0; time_t time1; struct tm *t1,*t2; pid_t pid,pids[MAXPRO+1]; long i,ti; int status; struct timeval tv1[TESTTIME],tv2[TESTTIME]; struct timezone tz; for (l=0;l max=0; gettimeofday (&tv1[l],&tz); //记录开始时间 myfork(); gettimeofday (&tv2[l],&tz); //记录结束时间 } for(l=0;l printf(\tv1[l].tv_sec,tv1[l].tv_usec); printf(\is %ds%dus \\n\l+1,tv2[l].tv_sec,tv2[l].tv_usec); ti=(tv2[l].tv_sec-tv1[l].tv_sec)*1000000+(tv2[l].tv_usec-tv1[l].tv_usec); printf(\ave+=ti/MAXPRO; printf(\} printf(\return 1; }
正在阅读:
实验2-进程的初步认识10-13
《不抱怨的世界》读书笔记范文03-22
b2b是什么意思02-19
艺术是一种社会的意识形态03-20
融媒体时代报纸发展出路探究04-15
2017年度安全生产目标责任书10-27
投资移民美国,到底需要多少钱?12-28
消防部队元旦春节战备教育教案04-20
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 初步
- 进程
- 认识
- 实验
- 关于量本利分析法的小结及其习题
- 专业综合课程设计 QPSK信号的调制解调
- 护患沟通座谈会记录本
- 模拟电子线路习题习题答案
- 山东省潍坊市2015届高三下学期二模考试数学(文)试题 Word版含答案
- 长春金融高等专科学校自主招生面试试题综合素质答案技巧
- 郑州市某中学教学楼土木混凝土课程设计样板 精品
- 201209学期建筑结构检测鉴定与加固作业1
- ARM嵌入式系统基础教程课后习题答案及练习题 - - 周立功
- 听雨与诗词
- 社会学概论形考任务二
- 北京市社会保障卡门诊就医须知
- 现代宇宙学理论的重正和修复
- 中班教案走进纸世界
- 2014 - 2015第二学期演示实验内容
- 软件工程试题(附答案)doc
- 郑州市第七届中等职业学校
- 廉政通讯稿
- 河南省天一大联考2018届高三上期期末考试英语试题
- 北京最值得逛的50个地方