当前位置:文档之家› 操作系统论文

操作系统论文

操作系统实验报告专业:计算机信息管理班级:姓名:学号:项目1 :进程创建项目1 进程创建报告我保证该作业是通过我本人的学习和研究独立完成的,作业中的引用部分均标明了出处1.题目编写一段C语言程序,使它产生具有如图1所示的进程结构。

进程1创建出2,3,4子进程。

子进程3创建出孙进程5和重孙进程62.解题思路(1)采用fork函数创建进程,当它返回0时,说明创建了子进程3.在子进程3中创建孙进程5,在孙进程中创建重孙进程6,当返回值大于0时,说明在父进程1中,在父进程1中创建进程2和6(2)在个进程中显示一条该进程的信息(3)用sleep函数使父进程挂起30s,给出查询进程信息的预留时间(4)在一终端编译并运行程序,另打开一个终端,用ps命令获取进程信息3.程序清单Ps命令格式:ps[options][pids]功能:显示正在执行的进程信息常用选项:-1 以长列表的形式列出-a 显示其他用户的进程-e 显示环境-r 只显示正在运行的程序栏目说明:UID 用户的标志号PID 进程的标志号,是系统赋予每个正在执行的进程的唯一编号PPID 父进程的标志号PRI 进程优先级SIZE 虚拟内存大小RSS 驻留空间大小STAT 进程状态 R—进程正在运行,S—睡眠,D—不可中断睡眠T—停止或跟踪Z—僵尸进程W—没有驻留页TTY 进程所在的虚拟终端号TIME 该进程已经运行的时间COMMAND 该进程的名称4.结果及其分析进程UNIX中,进程既是一个独立拥有资源的基本单位,又是一个独立调度的基本单位。

一个进程实体由若干个区(段)组成,包括程序区、数据区、栈区、共享存储区等。

每个区又分为若干页,每个进程配置有唯一的进程控制块PCB,用于控制和管理进程。

PCB的数据结构如下:(1)、进程表项(Process Table Entry)。

包括一些最常用的核心数据:进程标识符PID、用户标识符UID、进程状态、事件描述符、进程和U 区在内存或外存的地址、软中断信号、计时域、进程的大小、偏置值nice、指向就绪队列中下一个PCB的指针P_Link、指向U区进程正文、数据及栈在内存区域的指针。

(2)、U区(U Area)。

用于存放进程表项的一些扩充信息。

每一个进程都有一个私用的U区,其中含有:进程表项指针、真正用户标识符u-ruid(read user ID)、有效用户标识符u-euid(effective user ID)、用户文件描述符表、计时器、内部I/O参数、限制字段、差错字段、返回值、信号处理数组。

由于UNIX系统采用段页式存储管理,为了把段的起始虚地址变换为段在系统中的物理地址,便于实现区的共享,所以还有:(3)、系统区表项。

以存放各个段在物理存储器中的位置等信息。

系统把一个进程的虚地址空间划分为若干个连续的逻辑区,有正文区、数据区、栈区等。

这些区是可被共享和保护的独立实体,多个进程可共享一个区。

为了对区进行管理,核心中设置一个系统区表,各表项中记录了以下有关描述活动区的信息:区的类型和大小、区的状态、区在物理存储器中的位置、引用计数、指向文件索引结点的指针。

(4)、进程区表系统为每个进程配置了一张进程区表。

表中,每一项记录一个区的起始虚地址及指向系统区表中对应的区表项。

核心通过查找进程区表和系统区表,便可将区的逻辑地址变换为物理地址。

进程映像UNIX系统中,进程是进程映像的执行过程,也就是正在执行的进程实体。

它由三部分组成:(1)、用户级上、下文。

主要成分是用户程序;(2)、寄存器上、下文。

由CPU中的一些寄存器的内容组成,如PC,PSW,SP及通用寄存器等;(3)、系统级上、下文。

包括OS为管理进程所用的信息,有静态和动态之分。

所涉及的系统调用1、fork( )创建一个新进程。

系统调用格式:pid=fork( )参数定义:int fork( )fork( )返回值意义如下:0:在子进程中,pid变量保存的fork( )返回值为0,表示当前进程是子进程。

>0:在父进程中,pid变量保存的fork( )返回值为子进程的id值(进程唯一标识符)。

-1:创建失败。

如果fork( )调用成功,它向父进程返回子进程的PID,并向子进程返回0,即fork( )被调用了一次,但返回了两次。

此时OS在内存中建立一个新进程,所建的新进程是调用fork( )父进程(parent process)的副本,称为子进程(child process)。

子进程继承了父进程的许多特性,并具有与父进程完全相同的用户级上下文。

父进程与子进程并发执行。

核心为fork( )完成以下操作:(1)为新进程分配一进程表项和进程标识符进入fork( )后,核心检查系统是否有足够的资源来建立一个新进程。

若资源不足,则fork( )系统调用失败;否则,核心为新进程分配一进程表项和唯一的进程标识符。

(2)检查同时运行的进程数目超过预先规定的最大数目时,fork( )系统调用失败。

(3)拷贝进程表项中的数据将父进程的当前目录和所有已打开的数据拷贝到子进程表项中,并置进程的状态为“创建”状态。

(4)子进程继承父进程的所有文件对父进程当前目录和所有已打开的文件表项中的引用计数加1。

(5)为子进程创建进程上、下文进程创建结束,设子进程状态为“内存中就绪”并返回子进程的标识符。

(6)子进程执行虽然父进程与子进程程序完全相同,但每个进程都有自己的程序计数器PC(注意子进程的PC开始位置),然后根据pid变量保存的fork( )返回值的不同,执行了不同的分支语句。

fork( )调用前fork( )调用后PC源程序1#include <stdio.h>main( ){int p1,p2;while((p1=fork( ))= = -1); /*创建子进程p1*/if (p1= =0) putchar('b');else{while((p2=fork( ))= = -1); /*创建子进程p2*/if(p2= =0) putchar('c');else putchar('a');}}2、#include <stdio.h>main( ){int p1,p2,i;while((p1=fork( ))= = -1); /*创建子进程p1*/ if (p1= =0)for(i=0;i<10;i++)printf("daughter %d\n",i);else{while((p2=fork( ))= = -1); /*创建子进程p2*/if(p2= =0)for(i=0;i<10;i++)printf("son %d\n",i);elsefor(i=0;i<10;i++)printf("parent %d\n",i);}}运行结果5.参考文献[1]凤羽翚.计算机操作系统(第2版).北京:电子工业出版社,2009.[2]W.R.Stevens,S.A.Rago[美]著.尤晋元,张亚英,戚正伟译.UNIX环境高级编程.北京:人民邮电出版社,2006[3]蒋静,徐志伟.操作系统原理.技术与编程.北京:机械工业出版社,2004项目3 Socket通信项目3 网络编程报告我保证该作业是通过我本人的学习和研究独立完成的,作业中的引用部分均标明了出处1.题目编写一个微型的server和client程序Client从控制台读取字符串,送给server,接收server发来的字符串,显示在控制台Server把收到的来自client的信息加入“from server”,返回给客户端2.解题思路(1)使用Linux网络编程相关函数,socket, connect ,bind, listen,accept ,recv, send进行网络编程(2)Server程序①用socket函数创建网络连接②用bind函数绑定IP与创建的socket③用listen函数产生监听④用accept函数等待接入⑤用recv函数接收数据⑥用send函数发送数据(3)client程序①用socket函数创建网络连接②用connect函数建立连接③用recv函数接收数据④用send函数发送数据3.程序清单Socket模仿UNIX文件操作来实现进程通信操作,将网络通信看成网络上两端进程间的I/O操作。

因此定义了类似文件描述符的Socket描述符,以及与文件读写相似的数据接收和发送操作。

但是,由于建立打开文件结构,取得文件描述符是建立进程与本地文件静态资源之间的联系,而建立网络的连接需要指定协议,经过多次的握手(请求、应答)过程,故网络上的进程通信要比文件I/O考虑更多的情况。

Socket通信采用了客户,服务器模型,建立连接时,客户进程与服务器进程所做的工作是不对称的。

下图是Socket实现面向连接的进程通信基本过程。

源代码服务器端:#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <fcntl.h>#include <sys/stat.h>int main(int argc, char **argv){int sockfd,newsockfd,fd,n,length;struct sockaddr_in server;char buff[1024],rbuf[1024],* path;//open a socket and make the addresssockfd=socket(AF_INET,SOCK_STREAM,0); // 生成套接字server.sin_family=AF_INET;server.sin_addr.s_addr=INADDR_ANY;server.sin_port=0; // 选择一个已释放的端口号// 构成socked名(地址)和建立联系if(bind(sockfd,(struct sockaddr *)&server,sizeof(server))<0) return 1;length=sizeof(server);// print the information of the socket for clientif(getsockname(sockfd,(struct sockaddr *)&server,&length)<0) printf("getting socket name error\n");// 获取并打印端口号printf("getting socket name:%s\n",server.sin_addr.s_addr);printf("socket port #%d\n",ntohs(server.sin_port));// wait for connectinglisten(sockfd,5);while(1){newsockfd=accept(sockfd,(struct sockaddr *)0,(int *)0); //accept a new connectif(!fork()) // 创建子进程{close(sockfd);bzero(buff,sizeof(buff)); // 调用库函数,清缓冲区//receive the file from clientfd=open("out.txt",O_WRONLY|O_CREAT|O_TRUNC,0644);sleep(1);while((count=recv(sockfd,rbuf,len,0))>0){n=write(fd,rbuf,count);}close(fd);exit(0);}close(newsockfd);}return 0;}客户端:#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <fcntl.h>#include <sys/stat.h>int main(int argc,char **argv){int sockfd,fd,n;struct sockaddr_in client;struct hostent *hp,*gethostbyname();char rbuf[1024];sockfd=socket(AF_INET,SOCK_STREAM,0);// 生成套接字//receive arguments from main and fulfill it into socket address if((hp=gethostbyname(argv[1]))==NULL)// 与由命令行参数指定的主机建立连接return 1;client.sin_family=AF_INET;bcopy((char *)hp->h_addr,(char *)&client.sin_addr.s_addr,hp->h_length);client.sin_port=htons(atoi(argv[2]));// connect to hostif(connect(sockfd,(struct sockaddr *)&client,sizeof(client))<0) return 1;fd=open("in.txt",O_RDONLY,0644);while((n=read(fd,rbuf,1024))>0){if(n<1024)rbuf[n]='\0';send(sockfd,rbuf,n,0);}close(fd);close(sockfd);return 0;}clientserver4.结果极其分析客户端打开in.txt文件,依次读出其中的内容,并通过面向连接的Socket套接字发给服务器。

相关主题