操作系统实验报告2-进程间通信
- 格式:doc
- 大小:172.50 KB
- 文档页数:6
软件学院计算机课程实验报告册课程名称计算机操作系统实验学期 2011 年至 2012 年第 2 学期学生所在院(系)软件学院年级 11软件专业班级软工(1)班学生姓名朱水云学号 **********指导教师陈自刚实验最终成绩软件学院实验室制2012 年 4 月实验报告( 二 ) 实验名称:进程间通信实验时间:2012年4月18号实验性质应用性设计性综合性5,观察运行结果,并思考6,退出中断并写出实验报告调试过程:根据编译提示的错误进行修改四、实验结果:1消息的发送和接受运行结果:2.共享存储区的创建、附接和段接运行结果:五、疑难与小结:1.消息的创建,发送和接收小结:从理想的结果来说,应当是每当Client发送一个消息后,server 接收该消息,Client再发送下一条。
也就是说“(Client)sent”和“(server)received”的字样应该在屏幕上交替出现。
实际的结果大多是,先由 Client 发送两条消息,然后Server接收一条消息。
此后Client Server交替发送和接收消息.最后一次接收两条消息. Client 和Server 分别发送和接收了10条消息,与预期设想一致message的传送和控制并不保证完全同步,当一个程序不再激活状态的时候,它完全可能继续睡眠,造成上面现象,在多次send message 后才 receive message.这一点有助于理解消息转送的实现机理.2.共享存储区的创建、附接和段接运行的结果和预想的完全一样。
但在运行的过程中,发现每当client 发送一次数据后,server要等大约0.1秒才有响应。
同样,之后client又需要等待大约0.1秒才发送下一个数据。
出现上述的应答延迟的现象是程序设计的问题。
当client端发送了数据后,并没有任何措施通知server端数据已经发出,需要由client的查询才能感知。
此时,client端并没有放弃系统的控制权,仍然占用CPU的时间片。
《操作系统》实验报告年级、专业、班级 姓名进程间通信实验题目实验时间 2014.11.21 实验地点 A主0410实验成绩 实验性质 □验证性 □设计性 □综合性 教师评价:□算法/实验过程正确; □源程序/实验内容提交 □程序结构/实验步骤合理;□实验结果正确; □语法、语义正确; □报告规范;其他:评价教师签名:一、实验目的1. 了解管道通信的特点,掌握管道通信的使用方法。
2. 了解消息队列通信机制及原理,掌握消息队列相关系统调用的使用方法及功能。
3. 了解Linux系统共享存储区的原理及使用方法。
二、实验项目内容1. 管道通信(1)父进程创建管道和两个子进程p1和p2。
(2)子进程p1打开给定文件(如果没有,则创建文件),并向文件中写数据,写完关闭文件,然后向管道写入一条消息“ok",目的是通知进程p2可以读取文件内容了。
(3)子进程p2通过管道读取消息,如果消息是“ok”,则打开文件,读取文件内容,并将其输出到屏幕上,关闭文件.2. 消息队列(1)父进程创建消息队列和两个子进程p1和p2。
(2)子进程p1打开给定文件(如果没有,则创建文件),并向文件中写数据,写完关闭文件,然后向消息队列写入一条消息“1",目的是通知进程p2可以读取文件内容了。
(3)子进程p2从消息队列读取消息,如果收到消息,则打开文件,读取文件内容,并将其输出道屏幕上,关闭文件。
3. 共享存储(1)由父进程建立一块共享存储区,并创建两个子进程p1,p2,父进程负责查询存储区状态,以及删除该存储区。
(2)子进程p1链接到该共享存储区,然后向存储区写入数据,写完断开链接。
(3)子进程p2链接到该共享存储区,从存储区读数据,然后断开链接。
注意:为了便于各进程对存储区访问的同步,这里使用信号量方法。
三、实验过程或算法1. 管道通信#include<unistd.h>#include<stdio.h>#include<string.h>#include<stdlib.h>int main() {int pipefd[2];pid_t pid;char buf[100];int n;为0memset(buf, 0, sizeof(buf));//clear bufif(pipe(pipefd) < 0) {perror("pipe");exit(0);}pid = fork();if(pid == 0) { //child process 1close(pipefd[0]);//close read fdchar *msg="Hello,I am a Pipe user.";write(pipefd[1], msg, 50);}else if(pid > 0) {pid = fork();if(pid == 0) { //child process 2close(pipefd[1]);//close write fdread(pipefd[0], buf, sizeof(buf));fprintf(stdout, "read from pipe is:%s\n", buf);}else if(pid > 0) exit(0);}}2.消息队列//发送消息,msqid是队列id,msg是要发送的消息void sendmsg(int msqid,mymesg msg){printf("msqid:%d,msg:%s\n",msqid,msg.mtext);if((msgsnd(msqid, &msg, sizeof(msg.mtext), IPC_NOWAIT)) != 0){//消息发送函数printf("pid_1:send msg error!\n");}else{printf("pid_1:send msg: %s succeed!\n", msg.mtext);}}//接收消息,msqid是队列idint rcvmsg(int msqid){mymesg msg={0};AIT);int msg_len = msgrcv(msqid, &msg, sizeof(msg.mtext), 0, IPC_NOW //接收消息函数if(msg_len < 0){printf("pid_2:receive msg error!\n");return 0;}printf("pid_2:recv msg: %s\n", msg.mtext);return 1;}3.共享存储创建共享存储区 shmid = shmget(IPC_PRIV A TE, SIZE, IPC_CREAT|0600 ) ;//{if ( shmid < 0 )perror("get shm ipc_id error") ;return -1 ;}pid = fork() ;子进程p1if ( pid == 0 ){ //printf("I'm child1 process,my pid is %d.\n",getpid());P操作sem_p(sem_id); //链接到存储区 shmaddr = (char *)shmat( shmid, NULL, 0 ) ;//if ( (int)shmaddr == -1 ){perror("shmat addr error") ;return -1 ;}向存储区写数据strcpy( shmaddr, "Hi,This is share memory!\n") ;//shmdt( shmaddr ) ;//断开链接V操作sem_v(sem_id); //父进程} else if ( pid > 0) {//printf("I'm father process,my pid is %d.\n",getpid());pid = fork();sleep(1);子进程2创建if(pid==0){//printf("I'm child2 process,my pid is %d.\n",getpid());P操作sem_p(sem_id); //读取存储区状态到buf中flag = shmctl( shmid, IPC_STAT, &buf) ;//{if ( flag == -1 )perror("shmctl shm error") ;return -1 ;}printf("shm_segsz =%d bytes\n", buf.shm_segsz ) ;printf("parent pid=%d, shm_cpid = %d \n", getppid(), buf.shm_cpid ) ;printf("chlid pid=%d, shm_lpid = %d \n",pid, buf.shm_lpid ) ;printf("shm_segsz =%d \n", buf.shm_perm.mode );shmaddr = (char *) shmat(shmid, NULL, 0 ) ;链接到存储区,读取其中数据if ( (int)shmaddr == -1 ){//perror("shmat addr error") ;return -1 ;}//打印数据到屏幕printf("%s", shmaddr) ;V操作sem_v(sem_id); //断开链接shmdt( shmaddr) ;//}else{perror("fork error.") ;shmctl(shmid, IPC_RMID, NULL) ;}删除该存储区shmctl(shmid, IPC_RMID, NULL) ;//return 0 ;}四、实验结果及分析和(或)源程序调试过程(包含程序使用方法、程序运行截图),实验过程中遇到的问题分析与心得体会。
操作系统实验二实验报告一、实验目的本次操作系统实验二的主要目的是深入理解和掌握进程管理的相关概念和技术,包括进程的创建、执行、同步和通信。
通过实际编程和实验操作,提高对操作系统原理的认识,培养解决实际问题的能力。
二、实验环境本次实验使用的操作系统为 Windows 10,编程环境为 Visual Studio 2019。
三、实验内容及步骤(一)进程创建实验1、首先,创建一个新的 C++项目。
2、在项目中,使用 Windows API 函数`CreateProcess`来创建一个新的进程。
3、为新进程指定可执行文件的路径、命令行参数、进程属性等。
4、编写代码来等待新进程的结束,并获取其退出代码。
(二)进程同步实验1、设计一个生产者消费者问题的模型。
2、使用信号量来实现生产者和消费者进程之间的同步。
3、生产者进程不断生成数据并放入共享缓冲区,当缓冲区已满时等待。
4、消费者进程从共享缓冲区中取出数据进行处理,当缓冲区为空时等待。
(三)进程通信实验1、选择使用管道来实现进程之间的通信。
2、创建一个匿名管道,父进程和子进程分别读写管道的两端。
3、父进程向管道写入数据,子进程从管道读取数据并进行处理。
四、实验结果及分析(一)进程创建实验结果成功创建了新的进程,并能够获取到其退出代码。
通过观察进程的创建和执行过程,加深了对进程概念的理解。
(二)进程同步实验结果通过使用信号量,生产者和消费者进程能够正确地进行同步,避免了缓冲区的溢出和数据的丢失。
分析结果表明,信号量机制有效地解决了进程之间的资源竞争和协调问题。
(三)进程通信实验结果通过管道实现了父进程和子进程之间的数据通信。
数据能够准确地在进程之间传递,验证了管道通信的有效性。
五、遇到的问题及解决方法(一)在进程创建实验中,遇到了参数设置不正确导致进程创建失败的问题。
通过仔细查阅文档和调试,最终正确设置了参数,成功创建了进程。
(二)在进程同步实验中,出现了信号量使用不当导致死锁的情况。
操作系统实验报告6一、实验目的本次操作系统实验的主要目的是深入了解和掌握操作系统中进程管理、内存管理、文件系统等核心概念和相关技术,通过实际操作和观察,增强对操作系统工作原理的理解,并提高解决实际问题的能力。
二、实验环境本次实验使用的操作系统为 Windows 10,实验工具包括 Visual Studio 2019 等。
三、实验内容(一)进程管理实验1、创建多个进程,并观察它们的运行状态和资源占用情况。
通过编写简单的C++程序,使用Windows API 函数创建多个进程。
在程序中,设置不同的进程优先级和执行时间,观察操作系统如何调度这些进程,以及它们对 CPU 使用率和内存的影响。
2、进程间通信实现了进程间的管道通信和消息传递。
通过创建管道,让两个进程能够相互交换数据。
同时,还使用了 Windows 的消息机制,使进程之间能够发送和接收特定的消息。
(二)内存管理实验1、内存分配与释放使用 C++的动态内存分配函数(如`malloc` 和`free`),在程序运行时动态申请和释放内存。
观察内存使用情况,了解内存碎片的产生和处理。
2、虚拟内存管理研究了 Windows 操作系统的虚拟内存机制,通过查看系统的性能监视器,观察虚拟内存的使用情况,包括页面文件的大小和读写次数。
(三)文件系统实验1、文件操作进行了文件的创建、读取、写入、删除等基本操作。
通过编写程序,对不同类型的文件(如文本文件、二进制文件)进行处理,了解文件系统的工作原理。
2、目录操作实现了目录的创建、删除、遍历等功能。
了解了目录结构在文件系统中的组织方式和管理方法。
四、实验步骤(一)进程管理实验步骤1、打开 Visual Studio 2019,创建一个新的 C++控制台项目。
2、在项目中编写代码,使用`CreateProcess` 函数创建多个进程,并设置它们的优先级和执行时间。
3、编译并运行程序,通过任务管理器观察进程的运行状态和资源占用情况。
仲恺农业工程学院实验报告纸
计算机科学与工程(院、系)网络工程专业班组《操作系统》
学号姓名实验日期2011-5-24 教师评定
实验二进程通信
一.实验目的:
通过实验使学生进一步了解进程之间的各种通信方式、基本原理和不同操作系统中具体的实现。
基本能达到下列具体的目标:
1、理解进程消息通信的概念,如何实现两个创建进程之间的数据传递。
2、理解进程共享变量的进程通信。
二.实验内容:
1.选择Window或Linux,并选择该操作系统中一种进程通信的方式。
2.查找该进程通信的API使用方式,设计出一个合适的应用程序。
3.采用java语言实现该应用程序。
三.实验步骤:
这里可以实现两个人在同一局域网的聊天,程序可以自动扫描上线的用户。
如果需要与其中的用户进行交谈,则只需双击用户列表,输入对方IP,便可在下面的输入框内输入信息进行发送。
这个是三个人之间进行交谈,但是只能够实现相互两个人之间进行通信,方式跟上面的差不多。
但是三个人都可以看到发送的信息。
本机上的交谈信息
其他用户上的信息
四.实验心得:
这次的实验一开始是在课上有简单的弄了下,后来跟计算机网络的课程设计题目——聊天软件设计差不多一致,于是便这个当做了课题来进行课程设计,通过实现简单的聊天程序来完成进程间的通信。
这次的实验采用基于Java的程序设计技术,要用到很多Java socket的知识。
刚开始也得从网上找一些代码来看和了解一些新的知识。
计算机工程学院实验报告课程名称:操作系统实验班级实验成绩:指导教师:姓名:实验项目名称:进程与进程通信学号:上机实践日期:2009-11-13实验项目编号:实验二组号:上机实践时间:2学时一、目的1、深刻理解进程和线程的概念;2、掌握线程和进程的差别以及与之相适应的通信方式;3、掌握在Linux环境下创建进程: fork()的应用;4、了解用fork()创建进程、以及整个程序的运行过程;5、掌握多进程的程序设计与进程之间通信的方法;6、掌握共享内存、信号灯集实现进程通信的方法;7、理解、掌握Linux下文件系统,以及其安装与卸载过程。
二、实验内容1、在Linux环境下,用fork()创建多个进程,分别运行不同的函数;2、一部分进程代表读者,一部分进程代表写者;用共享内存、信号灯集机制实现各个读者、写者进程之间的通信;3、掌握shmget()、shmat()、shmctl()以及semget()、semctl()、semop()等函数在进程通信中的使用方法;4、用信号灯加PV操作实现进程间的互斥与同步。
三、实验环境1、操作系统:Red Hat Linux四、实验原理1、枚举数据类型,在信号灯集初始化时使用。
该结构在sys/sem.h中没有定义,必须程序设计者自行定义。
其中:semid—已经创建的信号灯集ID,sn—操作的元素的IDunion semun{int val;struct semid_ds *buf;ushort *array;};2、对信号灯集中的某个元素进行P操作。
首先要定义一个sembuf 类型的变量(该类型已经在sys/sem.h中预定义,可以直接引用),然后对该变量的各个元素进行赋值,注意进行P操作,主要是sem_op元素赋值为 -1。
其中:semid—已经创建的信号灯集ID,sn—操作的元素的IDvoid down(int semid,int sn){/* define P operating*/struct sembuf op;op.sem_num=sn;op.sem_op=-1;op.sem_flg=0;semop(semid,&op,1);}3、对信号灯集中的某个元素进行V操作。
Linux信号量实验报告一、实验目的深入理解操作系统中进程间通讯的本质二、实验方法利用UNIX/LINUX所提供的信号量、共享存储器、PV操作、文件锁等机制实现进程间的信息共享、进程间的互斥与同步。
三、实验任务编写一个C语言程序,该程序将一个存放了一个整数的文本文件内容执行加1操作一百万次,同时启动这个程序的多个副本,观察执行结果是否正确。
利用信号量机制对文件上锁,重新运行观察结果是否正确。
四、实验要点信号量概念、PV操作五、实验内容5.1 信号量概念信号量是一种确保特定代码段(临界区)只能被一个进程或者线程调用的一种机制。
在实际应用中,信号量由一种特殊的数据结构——信号量集所管理。
在使用信号量以前,需要创建一个信号量集,使用完成以后需要销毁信号量集。
信号量集的作用相当于一个信号量的计数器。
P操作是向信号量集获取一个信号量的操作,如果此时信号量集中有信号量,则会对信号量中的计数器进行更改(大部分情况下是计数器减一);如果此时信号量集中没有可用信号量(即计数器为0时),则执行P操作的线程或者进程则会被阻塞,直到信号量集中拥有可用的信号量(即计数器不为0)。
具体关系可用下图表示:5.2 信号量的初始化信号量的初始化需要用到两个函数(semget和semctl)和一个联合体结构(该实验中我们只需要用联合体结构中的val值,所以我只定义val变量)。
Semget系统调用的定义如下:int semget(key_t key, int nsems, int semflg)semget这个系统调用的作用是返回一个与key参数相关联的一个信号量集标识,semflg 参数会控制函数的行为;如果semflg为IPC_CREAT或者IPC_PRIVATE,则函数会创建一个拥有nsems个信号量的信号量集;如果semflg的值为IPC_CREAT | IPC_EXCL,在信号量集已经存在的情况下会发生错误。
实验中使用的获得信号量集标识的代码为:int sem_id = semget((key_t)2234, 0, 0);if (sem_id == -1){sem_id = semget((key_t)2234, 1, 0666 | IPC_CREAT);if (!init(sem_id)) return -1;}上述代码的第一行,nsems和semflg参数均为0,目的是只获得与2234这个值相关联的信号量集的标识;如果这个信号量集已经存在,则返回这个信号量集的标识;否则返回-1 下面就对获得的sem_id进行判断,如果值为-1,即信号量集还没有被创建,需要创建一个信号量集。
实验四:进程同步实验一、实验任务:1、熟悉操作系统进程通信原理2、设计程序,实现共享内存、管道通信、消息通信二、实验原理:1、进程间通信的几种方法简介(1)消息队列:消息队列是消息的链接表,包括Posix消息队列systemV消息队列。
有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。
(2)共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。
是针对其他通信机制运行效率较低而设计的。
往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
(3)无名管道(Pipe)及有名管道(named pipe):有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信;无名管道可用于有亲缘关系的进程之间彼此的通信,进行通信时候必须有一定的机制保证对管道写和读的互斥:即在读是要关闭写的端口,而在写的时候也要保证读的一端是关闭的。
2、进程通信函数(1)消息队列有关系统调用函数a.创建消息队列使用msgget()函数:#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>int msgget(key_t key, int flag) ;该函数成功调用返回消息队列标识符。
其中的key是关键字,可以由ftok()函数得到:key=ftok(“.”,’a’);其中”.”可以是任何目录,’a’是任意字符,即所有群组标识。
flag是标识,IPC_CREAT位表示创建,一般由服务器程序创建消息队列时使用。
如果是客户程序,必须打开现存的消息队列,必须不使用IPC_CREAT。
发送和接收的消息都必须使用一个类似msgbuf的结构表示,msgbuf结构定义如下:struct msgbuf{long mtype;char mtext[1];}上面的定义,消息内容只有一个字节,是不实用的,一般我们需要重新定义一个结构:struct amsgbuf{long mtype;char mtext[200];}其中的mtype都是消息类型。
实验报告学号姓名成绩__________实验二进程通信【实验目的和要求】1、了解进程通信的概念及方法;2、了解信号量、管道;3、掌握信号量、管道和命名管道编程方法。
【实验内容】1、利用命名管道实现单机QQ聊天;2、撰写实验报告;【实验原理】1、信号量(semaphore)是为那些访问相同资源的进程以及同一进程不同线程之间提供的一个同步机制。
它不是用于传输数据,而只是简单地协调对共享资源的访问。
信号量包含一个计数器,表示某个资源正在被访问和访问的次数,用来控制多进程对共享数据的访问。
一旦成功拥有了一个信号量,对它所能做的操作只有两种:请求和释放。
当执行释放操作时,系统将该信号值减1(如果小于零,则设置为零);当执行请求操作时,系统将该信号值加1,如果加1后的值大于设定的最大值,那么系统将会挂起处理进程,直到信号值小于最大值为止。
Tuxedo 用信号量来确保在某一时刻只有一个进程对某一块共享内存进程访问。
信号量配置太低会导致Tuxedo系统应用程序无法启动。
2、管道分为两种:管道和命名管道。
管道是UNIX系统IPC的最古老形式,并且所有的UNIX系统都提供这种通信机制。
可以在有亲缘关系(父子进程或者是兄弟进程之间)进行通信,管道的数据只能单向流动,如果想双向流动,必须创建两个管道。
管道应用的一个重大缺陷就是没有名字,因此只能用于亲缘进程之间的通信。
后来以管道为基础提出命名管道(namedpipe,FIFO)的概念,该限制得到了克服。
FIFO不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中。
这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信(能够访问该路径的进程以及FIFO的创建进程之间),因此,通过FIFO不相关的进程也能交换数据。
值得注意的是,FIFO严格遵循先进先出(first in first out)规则,对管道及FIFO的读总是从开始处返回数据,对它们的写则是把数据添加到末尾。
一、实验目的1. 理解进程通信的概念和作用。
2. 掌握进程通信的常用方法,包括管道、消息队列、信号量等。
3. 通过编程实践,加深对进程通信机制的理解和应用。
二、实验环境操作系统:Linux开发环境:gcc三、实验内容1. 管道通信2. 消息队列通信3. 信号量通信四、实验步骤及分析1. 管道通信(1)实验步骤1)创建一个父进程和一个子进程;2)在父进程中创建一个管道,并将管道的读端和写端分别赋给父进程和子进程;3)在父进程中,通过管道的写端发送数据给子进程;4)在子进程中,通过管道的读端接收父进程发送的数据;5)关闭管道的读端和写端;6)结束进程。
(2)实验分析通过管道通信,实现了父进程和子进程之间的数据传递。
管道是半双工通信,数据只能单向流动。
在本实验中,父进程向子进程发送数据,子进程接收数据。
2. 消息队列通信(1)实验步骤1)创建一个消息队列;2)在父进程中,向消息队列中发送消息;3)在子进程中,从消息队列中接收消息;4)删除消息队列;5)结束进程。
(2)实验分析消息队列是一种进程间通信机制,允许不同进程之间传递消息。
消息队列的创建、发送、接收和删除等操作都是通过系统调用实现的。
在本实验中,父进程向消息队列发送消息,子进程从消息队列接收消息,实现了进程间的消息传递。
3. 信号量通信(1)实验步骤1)创建一个信号量;2)在父进程中,对信号量执行P操作,请求资源;3)在子进程中,对信号量执行V操作,释放资源;4)结束进程。
(2)实验分析信号量是一种用于实现进程同步的机制。
在进程通信中,信号量可以用来协调多个进程对共享资源的访问。
在本实验中,父进程和子进程通过信号量实现了对共享资源的同步访问。
五、实验结果1. 管道通信实验结果:父进程成功向子进程发送数据,子进程成功接收数据。
2. 消息队列通信实验结果:父进程成功向消息队列发送消息,子进程成功从消息队列接收消息。
3. 信号量通信实验结果:父进程成功获取资源,子进程成功释放资源。