操作系统实验报告(进程间的共享存贮区和信号量通信)
操作系统实验报告
操作系统实验报告实验三、进程通信(一)——管道及共享内存一、实验目的1)加深对管道通信的了解2)掌握利用管道进行通信的程序设计3)了解共享内存通信的程序设计方法4)了解和熟悉Linux支持的共享存储区机制二、实验内容任务一、(1)阅读以上父子进程利用管道进行通信的例子(例1),写出程序的运行结果并分析。
(2)编写程序:父进程利用管道将一字符串交给子进程处理。
子进程读字符串,将里面的字符反向后再交给父进程,父进程最后读取并打印反向的字符串。
任务二、(1)阅读例2的程序,运行一次该程序,然后用ipcs命令查看系统中共享存储区的情况,再次执行该程序,再用ipcs命令查看系统中共享内存的情况,对两次的结果进行比较,并分析原因。
最后用ipcrm命令删除自己建立的共享存储区。
(有关ipcs和ipcrm介绍见后面一页)(2)每个同学登陆两个窗口,先在一个窗口中运行例3程序1(或者只登陆一个窗口,先在该窗口中以后台方式运行程序1),然后在另一个窗口中运行例3程序2,观察程序的运行结果并分析。
运行结束后可以用ctrl+c结束程序1的运行。
(3)编写程序:使用系统调用shmget(),shmat(),shmdt(),shmctl(),编制程序。
要求在父进程中生成一个30字节长的私有共享内存段。
接下来,设置一个指向共享内存段的字符指针,将一串大写字母写入到该指针指向的存贮区。
调用fork()生成子进程,让子进程显示共享内存段中的内容。
接着,将大写字母改成小写,子进程修改共享内存中的内容。
之后,子进程将脱接共享内存段并退出。
父进程在睡眠5秒后,在此显示共享内存段中的内容(此时已经是小写字母)。
三、代码及运行结果分析(1)阅读以上父子进程利用管道进行通信的例子(例1),写出程序的运行结果并分析实验代码:#include<stdio.h>main(){ int x,fd[2];char buf[30],s[30];pipe(fd);while ((x=fork())==-1);if (x==0){close(fd[0]);printf("Child Process!\n");strcpy(buf,"This is an example\n");write(fd[1],buf,30);exit(0);}else{close(fd[1]);printf("Parent Process!\n");read(fd[0],s,30);printf("%s\n",s);}}运行结果:分析:调用pipe(fd);创建一个管道后,接着调用fork()函数产生两个进程,首先开始执行子进程,关闭管道出口,通过管道入口向管道中写入内容。
操作系统进程通信(信号,共享存储区,消息队列)
letter.txt 内容为:operatingsystemlixin numbet.txt 内容为:12342007202314 ·结果分析及解释
1.首先输出提示信息 Enter some text: ,提示输入文本。 2.首先输入 operating system 1234 [][]\] ,包括字母数字和无效字符。 3.再次输出提示信息 Enter some text: 。 4.输入 lixin2007202314 5.再次输出提示信息 Enter some text: 后输入 quit 退出。 6.输出提示信息 Distributed over! (7)问题分析
strcpy(msg.text,"Enter some text:\n"); msgsnd(msgid,&msg,MAXSIZE,IPC_NOWAIT);//发送提示信息 kill(pid1,SIGUSR1);//向子进程 1 发送信号,以显示提示信息 sleep(1); 6.父进程使用 fgets()函数读入一行输入,fgets()函数读入结束时的回车符 并自动添加字符串结束符。 7.对于输入 “quit” 退出的解决,一开始使用函数 strncmp(buf,”quit”,4);但后 来考虑到输入诸如”quitxy”等字符床也会退出,因此将 strncmp 改为 strcmp 函数,具 体代码为: if(strcmp(buf,"quit\n. 共享存储区: 主要实现语句: shmid=shmget(key,size,flag); shmat(shmid,addr,flag); shmdt(addr); shmctl(shmid,cmd,buf)。 2. 消息队列: 主要实现语句: struct my_msg { long int my_msg_type;
实验三-进程通讯实验报告
实验三进程通讯实验报告【姓名】【学号】【实验题目】进程通讯——消息队列与共享存储区【实验目的】(1)掌握进程间通讯的编程方法;(2)加深对进程并发执行的理解;(3)学习利用消息队列和共享存储区实现进程通信的方法。
【实验内容】设计一个多进程并发运行的程序,它由不同的进程完成下列工作:(1)接收键盘输入进程负责接收用户的键盘输入,并以适当的方式将由键盘获得的数据交给其它进程处理。
(2)显示进程负责全部数据显示任务,包括键盘输入数据的显示和提示信息的显示。
(3)分发数据进程将键盘输入的数据分为3类,即字母、数字和其它,并分别将字母写入文件letter.txt 中,数字写入文件number.txt中,除字母和数字外其它数据丢弃。
【实验要求】1、程序能以适当的方式提示用户输入数据;2、提示用户有数据被丢弃;3、全部的显示任务必须由显示进程完成;4、整个程序能够连续处理多组输入数据,直到用户输入“quit”字符串,整个程序结束;5、进一步要求:同时采用共享存储区和消息2种方法实现进程之间的通信,并比较这2种通信方法的利弊。
【实验方法】1、利用fork()函数创建2个子进程,用一个父进程和两个子进程完成上面的三个实验任务,用子进程1实现分发数据任务,子进程2实现接受键盘输入任务,父进程实现全部的显示任务。
2、同时通过共享存储区和消息队列两种进程通讯方式实现上面三个进程之间的同步和互斥。
3、利用while()循环、kill()函数和signal()函数实现连续多组数据输入。
【程序结构】·数据结构:消息队列、字符数组;·程序结构:顺序结构、if-else分支结构和while循环结构;·主要算法:无特别算法【实验结果】1、有代表性的执行结果:[stud13@localhost stud13]$ cc ipc.c[stud13@localhost stud13]$ ./a.outPlease input a line:∟operatingsystem01234-=,.Your message is:operatingsystem01234-=,.The characters deserted are:-=,.Please input a line:∟xushengju6651001!@#$%^&*()Your message is:xushengju6651001!@#$%^&*()The characters deserted are:!@#$%^&*()Please input a line:∟Hello123Your message is:Hello123Please input a line:∟quit[stud13@localhost stud13]$ cat letter.txtOperatingsystemxushengjuHello[stud13@localhost stud13]$ cat number.txt 012346651001123[stud13@localhost stud13]$2、结果分析及解释:在创建子进程1时,由于先返回子进程的ID号,msgrcv(msgid,&msg,BUFSIZE,0,0)一直都是非0值,故循环等待。
《操作系统》实验报告
一、实验目的1. 理解进程的概念及其在操作系统中的作用。
2. 掌握进程的创建、调度、同步和通信机制。
3. 学习使用进程管理工具进行进程操作。
4. 提高对操作系统进程管理的理解和应用能力。
二、实验环境1. 操作系统:Windows 102. 软件环境:Visual Studio 20193. 实验工具:C++语言、进程管理工具(如Task Manager)三、实验内容1. 进程的创建与销毁2. 进程的调度策略3. 进程的同步与互斥4. 进程的通信机制四、实验步骤1. 进程的创建与销毁(1)创建进程使用C++语言编写一个简单的程序,创建一个新的进程。
程序如下:```cpp#include <iostream>#include <windows.h>int main() {// 创建进程STARTUPINFO si;PROCESS_INFORMATION pi;ZeroMemory(&si, sizeof(si));si.cb = sizeof(si);ZeroMemory(&pi, sizeof(pi));// 创建进程if (!CreateProcess(NULL, "notepad.exe", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {std::cout << "创建进程失败" << std::endl;return 1;}std::cout << "进程创建成功" << std::endl;// 等待进程结束WaitForSingleObject(pi.hProcess, INFINITE);// 销毁进程CloseHandle(pi.hProcess);CloseHandle(pi.hThread);return 0;}```(2)销毁进程在上面的程序中,通过调用`WaitForSingleObject(pi.hProcess, INFINITE)`函数等待进程结束,然后使用`CloseHandle(pi.hProcess)`和`CloseHandle(pi.hThread)`函数销毁进程。
操作系统进程通信报告
实验四:进程同步实验一、实验任务: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都是消息类型。
操作系统实验报告(进程间的共享存贮区和信号量通信)
case -1:perror("fork()");exit(0);case 0:do_child_loop(sem_set_id,FILE_NAME);exit(0);default:break;}}for(i = 0;i<10;i++){int child_status;wait(&child_status);}printf("main is done");fflush(stdout);return 0;}运行结果:二、共享主存段机制共享主存段为进程提供了直接通过主存进行通信的有效手段,不像消息缓存机制那样需要系统提供缓存,也不像pipe机制那样需要事先建立一个特殊文件,而是有通信双方直接访问某些共享虚拟存储器空间。
在系统V中,系统管理一组共享主存段控制块。
通信进程在使用共享主存段以前,首先提出申请,系统为止分配存储空间并返回共享主存段标识号。
一个共享段建立后,进程把它被附加到自己的虚拟存储空间中。
一个进程可以附加多个共享主存段。
一个主存段一旦被附加到进程的虚拟机空间后,对它的访问以其他虚拟机的访问完全相同。
但为了保证共享主存段数据完整性,通信的进程之间要互斥的进行访问。
当通信进程不再需要该共享主存段时,可使用命令将其与进程分离,从而使其进程的虚空间删除。
为了理解进程通过共享主存段的通信过程,下面举例,一个是进程向共享段写信息的例子:一个是进行从共享段读信息的例子。
代码如下:四、实验过程与分析一、信号量机制在第一个例子的程序中创建了5个并发子进程,互斥地对文件进行写操作,将自己的进程号写到文件中去,信号量的初值为1,当地一个进程执行update_file函数时首先将信号量值-1,(相当于P操作)致使其它进程等待无法操作文件,直到其结束后,将其值变为1后(相当于V操作),其它进程并发竞争对文件的写操作,并将自己的pid 写入文件中。
在linux中信号量机制的执行既步骤如下所示:(1)信号量的定义:struct semaphore {spinlock_t lock;unsigned int count;struct list_head wait_list;};在linux中,信号量用上述结构体表示,我们可以通过该结构体定义一个信号量。
进程通信的实验报告
一、实验目的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. 信号量通信实验结果:父进程成功获取资源,子进程成功释放资源。
进程通讯管理实验报告(3篇)
第1篇一、实验目的1. 理解进程通信的概念和原理;2. 掌握进程通信的常用机制和方法;3. 能够使用进程通信机制实现进程间的数据交换和同步;4. 增强对操作系统进程管理模块的理解。
二、实验环境1. 操作系统:Linux2. 编程语言:C3. 开发环境:GCC三、实验内容1. 进程间通信的管道机制2. 进程间通信的信号量机制3. 进程间通信的共享内存机制4. 进程间通信的消息队列机制四、实验步骤1. 管道机制(1)创建管道:使用pipe()函数创建管道,将管道文件描述符存储在两个变量中,分别用于读和写。
(2)创建进程:使用fork()函数创建子进程,实现父子进程间的通信。
(3)管道读写:在父进程中,使用read()函数读取子进程写入的数据;在子进程中,使用write()函数将数据写入管道。
(4)关闭管道:在管道读写结束后,关闭对应的管道文件描述符。
2. 信号量机制(1)创建信号量:使用sem_open()函数创建信号量,并初始化为1。
(2)获取信号量:使用sem_wait()函数获取信号量,实现进程同步。
(3)释放信号量:使用sem_post()函数释放信号量,实现进程同步。
(4)关闭信号量:使用sem_close()函数关闭信号量。
3. 共享内存机制(1)创建共享内存:使用mmap()函数创建共享内存区域,并初始化数据。
(2)映射共享内存:在父进程和子进程中,使用mmap()函数映射共享内存区域。
(3)读写共享内存:在父进程和子进程中,通过指针访问共享内存区域,实现数据交换。
(4)解除映射:在管道读写结束后,使用munmap()函数解除映射。
4. 消息队列机制(1)创建消息队列:使用msgget()函数创建消息队列,并初始化消息队列属性。
(2)发送消息:使用msgsnd()函数向消息队列发送消息。
(3)接收消息:使用msgrcv()函数从消息队列接收消息。
(4)删除消息队列:使用msgctl()函数删除消息队列。
实验一 进程通信操作系统实验报告
验
内
容
2.用pipe()创建一个管道,然后用fork()创建两个生产进程和两个消费进程,它们之间能过pipe()传递信息。
实
验
结果
遇到问题及解决方法
int i,pid,status;
for(i=0;i<4;i++) pid=wait(*status); i,pid,status;
实
验
结果
遇到问题及解决方法
retval=clone((void*)producer,&(stack[4095]),clone_flag, (void*&arg);此语句void*后缺少),正确语句应为:
retval=clone((void*)producer,&(stack[4095]),clone_flag, (void*)&arg);
for(i=0;i<4;i++) pid=wait(&status);
if(id==1) stcopy(w_buf,"ccc\0");
else strcpy(w_buf,"ddd\0");
此语句中stcopy词语写错,应改为strcpy,即
if(id==1) strcpy(w_buf,"ccc\0");
学年第学期
操作系统课程
实验报告
学院:
专业:
班级:
姓名:
学号:
任课教师:
实验日期:2017年4月11日
实验题目
实验一进程通信
实验地点
实验目的
1.理解Linux系统的进程通信机构(IPC)允许在任意进程间大批量地交换数据的过程。
操作系统实验报告 进程通信
Pipe(fd);
While ((pid1=fork())==-1;
If (pid1==0)
{
Printf(“child 1 will going on!\n”);
Lockf(fd[1],1,0);
Sprintf(outpipe,”child 1 process is sending message!”);
西北师范大学计算机科学与工程学院学生实验报告
学号
专业
计算机科学与技术
姓名
课程名称
操作系统实验
班级
2011级计师(1)班
实验名称
实验五进程通信
课程类型
必修类
一.实验目的:
(1)了解Linux系统中进程通信的基本原理;
(2)了解和掌握管道通信机制;
(3)了解和熟悉消息通信机制、共享存储区机制以及信号通信机制。
Wait(0);
Read(fd[0],inpipe,50);
Printf(“%s\n”,inpipe);
Exit(0);
}
}
}
四.分析分析实验结果
功能:使用系统调用pipe()建立一条管道线,两个子进程p1和p2分别向管道各写一句话,而父进程从管道中读出来自于两个子进程的信息,显示在屏幕上。
说明:Lockf(files,function,size)
二.实验内容
1.编写一段程序,实现进程的管道通信。
使用系统调用pipe( )建立一条管道,创建两个子进程P1和P2。让P1和P2分别向管道各写一句话:
Child 1 is sending a message!
Child 2 is sending a message!
操作系统实验---进程通信——共享存储区和信号量
实验报告实验题目姓名:学号:课程名称:操作系统实验所在学院:信息科学与工程学院专业班级:计算机任课教师:实验项目名称进程通信——共享存储区和信号量一、实验目的与要求:1、了解和熟悉共享存储机制2、了解和熟悉信号量机制3、熟悉信号量机制中使用的数据结构和信号量机制的操作以及控制。
4、了解共享主存段机制,学会对共享主存段的系统调用。
二、实验设备及软件:1、PC机一台2、Linux操作系统三、实验方法(原理、流程图)一、共享存储区1、共享存储区机制的概念共享存储区(Share Memory)是 UNIX 系统中通信速度最高的一种通信机制。
该机制可使若干进程共享主存中的某一个区域,且使该区域出现(映射)在多个进程的虚地址空间中。
另一方面,一个进程的虚地址空间中又可连接多个共享存储区,每个共享存储区都有自己的名字。
当进程间欲利用共享存储区进行通信时,必须先在主存中建立一共享存储区,然后将它附接到自己的虚地址空间上。
此后,进程对该区的访问操作,与对其虚地址空间的其它部分的操作完全相同。
进程之间便可通过对共享存储区中数据的读、写来进行直接通信。
图示列出二个进程通过共享一个共享存储区来进行通信的例子。
其中,进程 A 将建立的共享存储区附接到自己的 AA’区域,进程 B 将它附接到自己的 BB’区域。
应当指出,共享存储区机制只为进程提供了用于实现通信的共享存储区和对共享存储区进行操作的手段,然而并未提供对该区进行互斥访问及进程同步的措施。
因而当用户需要使用该机制时,必须自己设置同步和互斥措施才能保证实现正确的通信。
二、涉及的系统调用1、shmget( )创建、获得一个共享存储区。
系统调用格式: shmid=shmget(key,size,flag)参数定义: int shmget(key,size,flag);key_t key;int size,flag;其中,key是共享存储区的名字;size是其大小(以字节计);flag是用户设置的标志,如IPC_CREAT。
进程通信实验报告
操作系统实验报告(三)进程通信专业:软件工程姓名:XXX班级:XXX学号:XXX指导老师:XXX2013/12/3实验三:进程通信一.实验目的加深对进程通信的理解。
熟悉消息通信机制、共享存储器通信机制,进一步认识其与信号量通信的区别。
二.实验内容1)编程实现基于消息缓冲队列机制的进程通信数据结构和通信原语(创建消息、发送消息、接收消息);2)最后编写主函数对所做工作进行测试三.实验步骤(1)任务分析:实现进程通信,需要建立创建消息函数、发送消息函数、接收消息函数,需要用到进程中的Send和Receive原语(2)程序设计:a.总体设计:创建两个windows窗体应用程序,分别用于发送消息和接收消息,可以采用C#实现。
b.具体实现①创建应用程序Sendmessage,在windows窗体上放置一个文本框输入要发送的消息,一个按钮控件,单击按钮控件发送消息,编辑ButtonOnclick()事件,来编辑发送消息函数,发送后弹出消息发送成功对话框。
②创建应用程序Receivemessage,在windows窗口上放置一个文本框用于接收消息,放置一个Button按钮,并编辑ButtonOnclick()事件,来编辑接收消息函数,成功后弹出成功接收对话框。
③程序中的发送接收需要用到系统中的函数,将在实验代码中给与提示。
(4)调试与测试实验结果:发送消息:接收消息:四.实验总结进程通信实验主要是通过通信原语机制创建消息发送函数和消息接收函数来模拟实现进程间的通信,在实验过程中,一些通信机制不是太明确,通过在网上查找资料以及和同学们交流,最终完成了进程通信实验,通过这次实验,我对进程间的通信原理多了更深一步的了解,为学习操作系统知识建立了良好的实践基础。
五.附录①发送消息函数源码:using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;using System.Runtime.InteropServices;namespace WindowsFormsApplication1{public partial class Form1 : Form{public Form1(){InitializeComponent();}[DllImport("User32.dll", EntryPoint = "SendMessage")] private static extern int SendMessage(int hWnd,int Msg,int wParam,ref COPYDATASTRUCT lParam);[DllImport("User32.dll", EntryPoint = "FindWindow")] private static extern int FindWindow(string lpClassName, string lpWindowName);public struct COPYDATASTRUCT{public IntPtr dwData;public int cbData;[MarshalAs(UnmanagedType.LPStr)]public string lpData;}const int WM_COPYDATA = 0x004A;private void button1_Click(object sender, EventArgs e){Sent();MessageBox.Show("信息发送成功|", "提示?", MessageBoxButtons.OK);}private void Sent(){int WINDOW_HANDLER = FindWindow(null, @"接受信息");if (WINDOW_HANDLER != 0){byte[] sarr =System.Text.Encoding.Default.GetBytes(this.textBox1.Text);int len = sarr.Length;COPYDATASTRUCT cds;cds.dwData = (IntPtr)100;cds.lpData = this.textBox1.Text;cds.cbData = len + 1;SendMessage(WINDOW_HANDLER, WM_COPYDATA, 0, ref cds); } }}}②接收消息函数源码:using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;using System.Runtime.InteropServices;namespace WindowsFormsApplication2{public partial class Form1 : Form{string message;public Form1(){InitializeComponent();}public struct COPYDATASTRUCT{public IntPtr dwData;public int cbData;[MarshalAs(UnmanagedType.LPStr)]public string lpData;}const int WM_COPYDATA = 0x004A;private void button1_Click(object sender, EventArgs e) {Receive();}private void Receive(){textBox1.Text += "收到信息为"+ message + Environment.NewLine;MessageBox.Show("成功接收!");}protected override void DefWndProc(refSystem.Windows.Forms.Message m){switch (m.Msg){case WM_COPYDATA:COPYDATASTRUCT mystr = new COPYDATASTRUCT();Type mytype = mystr.GetType();mystr = (COPYDATASTRUCT)m.GetLParam(mytype); message = mystr.lpData;break;default:base.DefWndProc(ref m);break;}}}}。
计算机操作系统实验报告
计算机操作系统实验报告计算机操作系统实验报告引言:计算机操作系统作为计算机系统的核心组成部分,承担着管理和控制计算机硬件资源的重要任务。
通过实验,我们可以更好地理解操作系统的工作原理和功能,掌握操作系统的基本操作和管理技巧。
本文将结合实验结果,对操作系统实验进行总结和分析。
实验一:操作系统安装与配置在这个实验中,我们学习了操作系统的安装和配置过程。
通过选择合适的操作系统版本、设置分区和文件系统等步骤,成功地安装了操作系统。
同时,我们还学习了如何进行系统配置,包括网络设置、用户管理和软件安装等。
通过这个实验,我们对操作系统的基本安装和配置有了更深入的了解。
实验二:进程管理进程是操作系统中最基本的执行单位,也是操作系统资源管理的核心。
在这个实验中,我们学习了进程的创建、调度和终止等操作。
通过编写简单的程序,我们可以观察到进程的创建和调度过程,了解进程的状态转换和资源分配。
同时,我们还学习了进程间通信的方式,如共享内存和消息传递等。
通过这个实验,我们对进程管理有了更深入的理解。
实验三:内存管理内存管理是操作系统中重要的一部分,它负责管理和分配计算机的内存资源。
在这个实验中,我们学习了内存的分配和回收算法,如连续分配和非连续分配等。
通过编写程序,我们可以观察到内存的分配和回收过程,了解内存的管理策略和算法。
同时,我们还学习了虚拟内存的概念和实现原理,通过页面置换算法实现了虚拟内存的管理。
通过这个实验,我们对内存管理有了更深入的认识。
实验四:文件系统文件系统是操作系统中用于管理和存储文件的一种机制。
在这个实验中,我们学习了文件系统的基本操作和管理技巧。
通过创建文件、目录和链接等操作,我们可以更好地理解文件系统的结构和组织方式。
同时,我们还学习了文件的读写和权限管理等操作,通过编写程序实现了对文件的操作。
通过这个实验,我们对文件系统有了更深入的了解。
实验五:设备管理设备管理是操作系统中负责管理和控制计算机设备的一种机制。
实验三操作系统进程间通信
实验三操作系统进程间通信实验三进程间通信班级:计科f1406 姓名:王家平学号:201416010619一、实验目的:Linux系统的进程通信机构(IPC)允许在任意进程间大批量的交换数据。
本实验的目的是了解和熟悉Linux支持的通信机制、共享存储区机制及信号量机制。
二、实验预备内容:阅读Linux系统的msg.c sem.c shm.c等源码文件,熟悉Linux的三种通信机制。
三、实验内容:(1) 消息的创建,发送和接收(2) 使用系统调用msgget(),msgsnd(), msgrev()及msgctl()编制一长度为1k的消息发送和接收程序。
<程序设计>(1) 为了便于操作和观察结果,用一个程序作为“引子”,先后fork()两个子进程,SERVER和CLIENT,进行通信。
2) SERVER端建立一个Key为75的消息队列,等待其他进程发来的消息。
当遇(到类型为1的消息,则作为结束信号,取消该队列,并退出SERVER。
SERVER 每接收到一个消息后显示一句“(server)received”。
(3) CLIENT端使用Key为75的消息队列,先后发送类型从10到1的消息,然后退出。
最后一个消息,即是SERVER端需要的结束信号。
CLIENT每发送一条信息后显示一句“(client)sent”。
(4) 父进程在SERVER和CLIENT均退出后结束。
(5)四(实验代码1.#include <stdio.h>#include <sys/types.h>#include <sys/msg.h>#include <sys/ipc.h>#define MSGKEY 75struct msgform{long mtype;char mtext[1030];}msg;int msgqid,i;void CLIENT(){ int i;msgqid=msgget(MSGKEY,0777);for (i=10;i>=1;i--){msg.mtype=i;printf("(client)sent \n");msgsnd(msgqid,&msg,1024,0); /*发送消息msg入msgid消息队列*/ }exit(0);}void SERVER(){msgqid=msgget(MSGKEY,0777|IPC_CREAT); /*由关键字获得消息队列*/ do{msgrcv(msgqid,&msg,1030,0,0); /*从msgid消息队列接收消息msg*/ printf("(server)received \n");}while(msg.mtype!=1); /*消息类型为1时,释放队列*/msgctl(msgqid,IPC_RMID,0);exit(0);}void main(){while((i=fork())==-1);if(!i) SERVER();while((i=fork())==-1);if(!i) CLIENT();wait(0);wait(0);}2.#include <stdio.h>#include <sys/types.h>#include <sys/msg.h>#include <sys/ipc.h>#define MSGKEY 75struct msgform{long mtype;char mtext[1030];}msg;int msgqid,i;CLIENT(){ int i;msgqid=msgget(MSGKEY,0777);for (i=10;i>=1;i--){msg.mtype=i;printf("(client)sent \n");msgsnd(msgqid,&msg,1024,0); /*发送消息msg入msgid消息队列*/ }exit(0);}main(){while((i=fork())==-1); if(!i) CLIENT();wait(0);}。
进程间基于共享存储区的通信 操作系统实验报告5
注释
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<stdio.h>
#include<stdlib.h>
#define SHMKEY 90
#define K 50
int shmid;
main()
{
int i,*pint,p1,p2;
编写一段程序,同时父进程创建两个子进程p1和p2;并使子进程p1与子进程p2通过共享存储区相互发送数据(512字节)。掌握系统调用shmget()、shmat()、shmdt()、shmctl()的使用方法及其功能,理解共享存储区通信原理;系统理解linux的三种通信机制。
实现的思想、方法和技术(含数据结构、算法)
//共享区首地址
//通过循环往共享区内写入依次数字1~24
//共享区第一个字中写入长度24,以便接收进程读
等待接收进程读
//取共享存储区SHMKEY的id
连接共享区
//共享区的第一个字节为零时,等待,因为还没写完
打印共享区中的内容
结果分析(含实现中出错原因分析)
实验心得:
[思考问题]
(1)共享存储区与消息通信有何区别?
pint=(int *)addr;
for(i=91;i>=64;i--)
*pint++=i;
pint=(int *)addr;
*pint=0;
shmctl(shmid,IPC_RMID,0);
exit(0);
}
}
}
//共享存储区所用的头文件
进程的共享主存通信实验报告总结
进程的共享主存通信实验报告总结
这个实验主要是针对进程之间共享主存的通信进行实验和研究。
在实
验中,我们使用了C语言作为开发工具,通过创建多个进程来模拟进
程之间的通信。
实验结果表明,通过共享主存的方式可以有效地实现
进程之间的通信。
在实验中,我们使用了共享内存的方式来实现主存
的共享。
通过这种方式,多个进程可以同时访问和修改同一块内存区域,从而实现数据交换和通信。
在实验过程中,我们遇到了一些问题和挑战。
首先是进程同步的问题。
由于多个进程可以同时访问共享内存,因此需要采取一定的措施来确
保数据的一致性。
在实验中,我们使用了信号量来实现进程的同步操作,以保证进程之间的读写操作按照一定的顺序进行。
另外一个挑战
是内存管理的问题。
由于多个进程同时访问同一块内存区域,如果不
进行合理的管理和控制,可能会导致内存泄露和数据丢失的问题。
在
实验中,我们采取了合适的内存管理策略,确保了内存的有效利用和
数据的安全性。
通过这个实验,我们深入理解了进程之间通信的原理和方法。
通过实
际操作和实验结果的分析,我们对进程通信的机制和实现方式有了更
深入的了解。
在今后的工作中,我们可以将这些知识和经验应用到实
际的开发和项目中,提高进程通信的效率和可靠性。
计算机操作系统实验报告(共享内存管理)
数学与计算机科学系实验报告课程:计算机操作系统地点:软件实验室二时间:2013年5月17 日#include <sys/ipc.h>#include <sys/sem.h>#include <sys/shm.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <signal.h>/* The union for semctl may or may not be defined for us.This code,defined in linux's semctl() manpage,is the proper way to attain it if necessary */ #if defined (__GNU_LIBRARY__)&& !defined (_SEM_SEMUN_UNDEFINED) /* union semun is defined by including <sys/sem.h> */#else/* according to X/OPEN we have to define it ourselves */union semun{int val;/* value for SETVAL */struct semid_ds *buf;/* buffer for IPC_STAT,IPC_SET */unsigned short int *array;/* array for GETALL,SETALL */struct seminfo *__buf;/* buffer for IPC_INFO */};#endif#define SHMDATASIZE1000#define BUFFERSIZE (SHMDATASIZE - sizeof(int))#define SN_READ 0#define SN_WRITE 1#define SN_LOCK 2int Semid = 0;void reader(int shmid);void writer(int shmid);int masterinit(void);char *standardinit(int shmid,int *semid);void delete(void);void sigdelete(int signum);void locksem(int semid,int semnum);void unlocksem(int semid,int semnum);void write(int shmid,int semid,char *buffer);int mysemget(key_t key,int nsems,int semflg);int mysemctl(int shmid,int semnum,int cmd,union semun arg);int mysemop(int semid,struct sembuf *sops,unsigned nsops);int myshmget(key_t key,int size,int shmflg);void *myshmat(int shmid,const void *shmaddr,int shmflg);int myshmctl(int shmid,int cmd,struct shmid_ds *buf);int main(int argc,char *argv[]){char selection[3];int shmid;/* 没有参数,则为master */if(argc < 2){shmid = masterinit();}else{shmid = atoi(argv[1]);}printf(" do you want a writer(1) or reader(2) ?");fgets(selection,sizeof(selection),stdin);switch(selection[0]){case '1':writer(shmid); break;case '2':reader(shmid);break;default:printf(" invalid choice, quit \n");}return 0;}void reader(int shmid){int semid;char *buffer;buffer = standardinit(shmid,&semid);printf("\n reader begin to run,and the id of share memory is %d, semaphore id is %d \n",shmid,semid);while(1){printf("\n wait for writer to input information ...");fflush(stdout);printf("finish \n");printf(" wait for locking semaphore SN_LOCK ...");fflush(stdout);locksem(semid,SN_LOCK);printf("finish \n");printf("received information: %s \n",buffer);unlocksem(semid,SN_LOCK);unlocksem(semid,SN_READ);}}void writer(int shmid){int semid;char *buffer;buffer = standardinit(shmid,&semid);printf("writer begin to run,the id of share memory is %d, semaphore id is %d\n",shmid,semid);while(1){char input[3];printf("\n menu \n 1.send a message \n");printf(" 2.quit \n");printf("input your choice(1-2):");fgets(input,sizeof(input),stdin);switch(input[0]){case '1':write(shmid,semid,buffer);break;case '2':exit(0);break;}}}char *standardinit(int shmid,int *semid){void *shmdata;char *buffer;shmdata = myshmat(shmid,0,0);*semid = *(int *)shmdata;buffer = shmdata + sizeof(int);return buffer;}int masterinit(void){union semun sunion;int semid,shmid;void *shmdata;/* 首先:我们要创建信号量*/semid = mysemget(IPC_PRIVATE,3,SHM_R|SHM_W);Semid = semid;/* 当进程离开时,删除信号量*/atexit(&delete);signal(SIGINT,&sigdelete);/* 信号量SN_READ 初始化为1(锁定),SN_WRITE 初始化为0(未锁定)*//* 信号量SN_LOCK 初始化为1(锁定)*/sunion.val = 1;mysemctl(semid,SN_READ,SETVAL,sunion);mysemctl(semid,SN_LOCK,SETVAL,sunion);sunion.val = 0;mysemctl(semid,SN_WRITE,SETVAL,sunion);/* 现在创建一块共享内存*/shmid = myshmget(IPC_PRIVATE,SHMDATASIZE,IPC_CREAT|SHM_R|SHM_W); /* 将该共享内存映射进进程的虚存空间*/shmdata = myshmat(shmid,0,0);/* 将该共享内存标志为已销毁的,这样在使用完毕后,将被自动销毁*/myshmctl(shmid,IPC_RMID,NULL);/* 将信号量的标识符写入共享内存,以通知其它的进程*/*(int *)shmdata = semid;printf("*** begin to run, and semaphore id is %d \n",shmid);return shmid;}void delete(void){printf("\n quit; delete the semaphore %d \n",Semid);union semun senion;senion.val=0;if(mysemctl(Semid,0,IPC_RMID,senion) == -1){printf("Error releasing semaphore. \n");}}void sigdelete(int signum){/* Calling exit will conveniently trigger the normal delete item. */ exit(0);}void locksem(int semid,int semnum){struct sembuf sb;sb.sem_num = semnum;sb.sem_op = -1;sb.sem_flg = SEM_UNDO;mysemop(semid,&sb,1);}void unlocksem(int semid,int semnum){struct sembuf sb;sb.sem_num = semnum;sb.sem_op = 1;sb.sem_flg = SEM_UNDO;mysemop(semid,&sb,1);}void waitzero(int semid,int semnum){struct sembuf sb;sb.sem_num = semnum;sb.sem_op = 0;sb.sem_flg = 0;/* No modification so no need to undo */mysemop(semid,&sb,1);void write(int shmid,int semid,char *buffer){printf("\n wait for reader to read in information ...");fflush(stdout);locksem(semid,SN_READ);printf("finish; wait for locking semaphore SN_LOCK...\n");fflush(stdout);locksem(semid,SN_LOCK);printf("please input information:");fgets(buffer,BUFFERSIZE,stdin);unlocksem(semid,SN_LOCK);unlocksem(semid,SN_WRITE);}int mysemget(key_t key,int nsems,int semflg){int retval;retval = semget(key,nsems,semflg);if(retval == -1){printf("semget key %d,nsems %d failed: %s ",key,nsems,strerror(errno)); exit(255);}return retval;}int mysemctl(int semid,int semnum,int cmd,union semun arg){int retval;retval = semctl(semid,semnum,cmd,arg);if(retval == -1){printf("semctl semid %d,semnum %d,cmd %dfailed: %s",semid,semnum,cmd,strerror(errno));exit(255);}return retval;int mysemop(int semid,struct sembuf *sops,unsigned nsops){int retval;retval = semop(semid,sops,nsops);if(retval == -1){printf("semop semid %d (%d operations) failed: %s",semid,nsops,strerror(errno)); exit(255);}return retval;}int myshmget(key_t key,int size,int shmflg){int retval;retval = shmget(key,size,shmflg);if(retval == -1){printf("shmget key %d,size %d failed: %s",key,size,strerror(errno));exit(255);}return retval;}void *myshmat(int shmid,const void *shmaddr,int shmflg){void *retval;retval = shmat(shmid,shmaddr,shmflg);if(retval == (void*) -1){printf("shmat shmid %d failed: %s",shmid,strerror(errno));exit(255);}return retval;}。
进程共享内存实验报告
一、实验目的1. 理解进程共享内存的概念和原理;2. 掌握在Linux环境下使用共享内存进行进程间通信的方法;3. 通过实验验证共享内存的通信效率和同步机制。
二、实验环境1. 操作系统:Linux2. 编程语言:C3. 开发环境:GCC编译器三、实验原理共享内存(Shared Memory)是Linux系统中实现进程间通信的一种方式。
它允许多个进程共享一块物理内存,使得这些进程可以直接访问这块内存区域,从而实现高效的数据交换。
共享内存的原理如下:1. 操作系统为共享内存分配一块物理内存区域;2. 将这块物理内存映射到各个进程的虚拟地址空间中;3. 进程通过访问虚拟地址空间中的共享内存区域,实现对共享内存的读写操作。
为了确保多个进程对共享内存的访问互不干扰,需要使用同步机制,如互斥锁(Mutex)和信号量(Semaphore)。
四、实验步骤1. 创建共享内存```c#include <sys/ipc.h>#include <sys/shm.h>int main() {key_t key = ftok("shared_memory", 65);int shmid = shmget(key, sizeof(int), 0666 | IPC_CREAT);if (shmid == -1) {perror("shmget");return 1;}return shmid;}```2. 映射共享内存```c#include <sys/mman.h>int main() {int shmid = 12345; // 假设已经获取了共享内存的IDint shared_memory = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);if (shared_memory == MAP_FAILED) {perror("mmap");return 1;}return 0;}```3. 写入数据```c#include <stdio.h>int main() {int shmid = 12345; // 假设已经获取了共享内存的IDint shared_memory = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);if (shared_memory == MAP_FAILED) {perror("mmap");return 1;}shared_memory = 100;printf("Shared memory value: %d\n", shared_memory);return 0;}```4. 读取数据```c#include <stdio.h>int main() {int shmid = 12345; // 假设已经获取了共享内存的IDint shared_memory = mmap(NULL, sizeof(int), PROT_READ, MAP_SHARED, shmid, 0);if (shared_memory == MAP_FAILED) {perror("mmap");return 1;}printf("Shared memory value: %d\n", shared_memory);return 0;}```5. 销毁共享内存```c#include <sys/ipc.h>#include <sys/shm.h>int main() {int shmid = 12345; // 假设已经获取了共享内存的IDif (shmctl(shmid, IPC_RMID, NULL) == -1) {perror("shmctl");return 1;}return 0;}```五、实验结果与分析1. 实验成功创建了共享内存,并通过mmap将其映射到进程的虚拟地址空间;2. 通过读写操作,验证了共享内存的通信效率和同步机制;3. 在多个进程之间使用共享内存进行通信,实现了高效的数据交换。
操作系统课程实验报告
操作系统课程实验报告一、实验目的操作系统是计算机系统中最为关键的软件之一,它负责管理计算机的硬件资源和软件资源,为用户提供一个良好的工作环境。
通过操作系统课程实验,旨在深入理解操作系统的基本原理和功能,提高对操作系统的实际操作能力和问题解决能力。
二、实验环境本次实验使用的操作系统为Windows 10 和Linux(Ubuntu 1804),开发工具包括 Visual Studio Code、gcc 编译器等。
三、实验内容(一)进程管理1、进程创建与终止在 Windows 系统中,使用 C++语言创建多个进程,并通过进程句柄控制进程的终止。
在 Linux 系统中,使用 fork()系统调用创建子进程,并通过 exit()函数终止进程。
2、进程同步与互斥使用信号量实现进程之间的同步与互斥。
在 Windows 中,利用CreateSemaphore()和 WaitForSingleObject()等函数进行操作;在Linux 中,通过 sem_init()、sem_wait()和 sem_post()等函数实现。
(二)内存管理1、内存分配与释放在 Windows 中,使用 HeapAlloc()和 HeapFree()函数进行动态内存的分配与释放。
在 Linux 中,使用 malloc()和 free()函数完成相同的操作。
2、内存页面置换算法实现了几种常见的内存页面置换算法,如先进先出(FIFO)算法、最近最少使用(LRU)算法等,并比较它们的性能。
(三)文件系统管理1、文件创建与读写在 Windows 和 Linux 系统中,分别使用相应的 API 和系统调用创建文件,并进行读写操作。
2、目录操作实现了目录的创建、删除、遍历等功能。
四、实验步骤(一)进程管理实验1、进程创建与终止(1)在 Windows 系统中,编写 C++程序,使用 CreateProcess()函数创建新进程,并通过 TerminateProcess()函数终止指定进程。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
case -1:
perror("fork()");
exit(0);
case 0:
do_child_loop(sem_set_id,FILE_NAME);
exit(0);
default:break;
}
}
for(i = 0;i<10;i++){
int child_status;
wait(&child_status);
}
printf("main is done");
fflush(stdout);
return 0;
}
运行结果:
二、共享主存段机制
共享主存段为进程提供了直接通过主存进行通信的有效手段,不像消息缓存机制那样需要系统提供缓存,也不像pipe机制那样需要事先建立一个特殊文件,而是有通信双方直接访问某些共享虚拟存储器空间。
在系统V中,系统管理一组共享主存段控制块。
通信进程在使用共享主存段以前,首先提出申请,系统为止分配存储空间并返回共享主存段标识号。
一个共享段建立后,进程把它被附加到自己的虚拟存储空间中。
一个进程可以附加多个共享主存段。
一个主存段一旦被附加到进程的虚拟机空间后,对它的访问以其他虚拟机的访问完全相同。
但为了保证共享主存段数据完整性,通信的进程之间要互斥的进行访问。
当通信进程不再需要该共享主存段时,可使用命令将其与进程分离,从而使其进程的虚空间删除。
为了理解进程通过共享主存段的通信过程,下面举例,一个是进程向共享段写信息的例子:一个是进行从共享段读信息的例子。
代码如下:
四、实验过程与分析
一、信号量机制
在第一个例子的程序中创建了5个并发子进程,互斥地对文件进行写操作,将自己的进程号写到文件中去,信号量的初值为1,当地一个进程执行update_file函数时首先将信号量值-1,(相当于P操作)致使其它进程等待无法操作文件,直到其结束后,将其值变为1后(相当于V操作),其它进程并发竞争对文件的写操作,并将自己的pid 写入文件中。
在linux中信号量机制的执行既步骤如下所示:
(1)信号量的定义:
struct semaphore {
spinlock_t lock;
unsigned int count;
struct list_head wait_list;
};
在linux中,信号量用上述结构体表示,我们可以通过该结构体定义一个信号量。
(2)信号量的初始化:
可用void sema_init(struct semaphore *sem, int val);直接创建,其中val为信号量初值。
也可以用两个宏来定义和初始化信号量的值为1或0:
DECLARE_MUTEX(name) : 定义信号量name并初始化为1
DECLARE_MUTEX_LOCKED(name) : 定义信号量name并初始化为0
还可以用下面的函数初始化:
void init_MUTEX(struct semaphore *sem); //初始化信号量的值为1
void init_MUTEX_LOCKED(struct semaphore *sem); //初始化信号量的值为0 (3)信号量的原子操作:
p操作:
* void down(struct semaphore *sem); //用来获取信号量,如果信号量值大于或等于0,获取
信号量,否则进入睡眠状态,睡眠状态不可唤醒
* void down_interruptible(struct semephore *sem); //用来获取信号量,如果。