操作系统实验导航
实验一:银行家算法 https://blog.youkuaiyun.com/weixin_46291251/article/details/115384510
实验二:多级队列调度和多级反馈队列调度算法 https://blog.youkuaiyun.com/weixin_46291251/article/details/115530582
实验三:动态分区式内存管理 https://blog.youkuaiyun.com/weixin_46291251/article/details/115772341
实验四:Linux下多进程通信 https://blog.youkuaiyun.com/weixin_46291251/article/details/116274665
实验五:进程通信的三种方式 https://blog.youkuaiyun.com/weixin_46291251/article/details/116301250
实验六:Linux文件系统实验 https://blog.youkuaiyun.com/weixin_46291251/article/details/116423798
实验七:自制简单U盘引导程序 https://blog.youkuaiyun.com/weixin_46291251/article/details/116427629
实验八:磁盘调度算法 https://blog.youkuaiyun.com/weixin_46291251/article/details/116431907
实验九:请求分页系统中的置换算法 https://blog.youkuaiyun.com/weixin_46291251/article/details/116443021
学习笔记:操作系统复习笔记 https://blog.youkuaiyun.com/weixin_46291251/article/details/117086851
背景:(关于进程通信的几种方式)
题目描述:
编写一主程序可以由用户选择如下三种进程通信方式:
-
使用管道来实现父子进程之间的进程通信
子进程向父进程发送自己的进程标识符,以及字符串“is sending a message to parent”。父进程则通过管道读出子进程发来的消息,将消息显示在屏幕上,然后终止。 -
使用共享存储区来实现两个进程之间的进程通信
进程 A 创建一个长度为 512 字节的共享内存,并显示写入该共享内存的数据;进程 B 将共享内存附加到自己的地址空间,并向共享内存中写入数据。 -
使用消息缓冲队列来实现 client 进程和 server 进程之间的通信
server 进程先建立一个关键字为 SVKEY(如 75)的消息队列,然后等待接收类型为 REQ(例如 1)的消息;
在收到请求消息后,它便显示字符串“serving for client”和接收到的 client 进程的进程标识数,表示正在为 client 进程服务;
然后再向 client 进程发送应答消息,该消息的类型是 client 进程的进程标识数,而正文则是 server 进程自己的标识ID。
client 进程则向消息队列发送类型为 REQ 的消息(消息的正文为自己的进程标识 ID) 以取得 sever 进程的服务,并等待 server 进程发来的应答;
然后显示字符串“receive reply from”和接收到的 server 进程的标识 ID。
算法设计:
管道:
对管道的设计类似于上一篇文章:Linux下两个子进程通过管道(pipe)通信
共享缓冲区:
共享内存是操作系统常采用的进程间通信方式。它使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据的更新。这种通信方式需要依靠某种同步机制,如互斥锁和信号量等。
共享内存通过系统调用 shmget()、shmat()、shmdt()、shmctl()来实现.
- 系统调用:shmget()
原型:int shmget(key_t key, int size, int shmflg)
参数:
Key:共享存储区的名字;
Size:共享存储区的大小(以字节计);
Shmflag:用户设置的标志,如 IPC_CREAT,IPC_CREAT 表示若系统中尚无指名的共享存储区,则由核心建立一个共享存储区;如系统中已有共享存储区,便忽略 IPC_CREAT。
返回值:
成功返回共享内存的标识符;不成功返回-1 - 系统调用:shmat()
原型:void* shmat(int shmid, const void *shmaddr, int shmflg);
参数:
Shmid:共享存储区的标识符;
Shmaddr:用户给定的,将共享存储区附接到进程的虚拟地址空间;
Shmflg:规定共享存储区的读、写权限,以及系统是否应对用户规定的地址做舍入操作。其值为 SHM_RDONLY 时,表示只能读,其值为 0 时,表示可读、可写,其值为 SHM_RND(取整)时,表示操作系统在必要时舍去这个地址。返回值:
该系统调用的返回值为共享存储区所附接到的进程虚地址。 - 系统调用:shmdt()
原型:int shmdt(void *shmaddr)参数:
Shmaddr:要断开连接的虚地址,亦即以前由连接的系统调用 shmat()所返回的虚地址。
返回值:
调用成功时,返回 0 值,调用不成功,返回-1 值。 - 系统调用:shmctl()
原型:int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数:
Shmid:由 shmget 所返回的标识符;
Cmd:是操作命令,可以分多种类型:
(1)用于查询有关共享存储区的情况。如其长度、当前连接的进程数、共享区的创建者标识符。
(2)用于设置或改变共享存储区的属性,如共享存储区的许可权、当前连接的进程计数等。
(3)对共享存储区的加锁和解锁命令。
(4)删除共享存储区标识符等。
Buf:用户缓冲区地址。返回值:
调用成功则返回 0,如果失败则返回-1。
创建共享缓冲区并等待被写入,然后读取:
//共享存储区
shmid=shmget(SHMKEY,512,0777|IPC_CREAT); /*创建共享存储区*/
printf("进程%d创建了共享存储区:\n",getpid());
addr=shmat(shmid,0,0); /*获取首地址*/
*addr=-1;
while (*addr == -1);//阻塞,用于进程同步
printf("进程%d读取共享存储区:%d\n",getpid(),*addr);
等待共享缓冲区被创建,然后写入:
//共享存储区
shmid=shmget(SHMKEY,512,0777); /*打开共享存储区*/
addr=shmat(shmid,0,0); /*获得共享存储区首地址*/
while(*addr != -1);//阻塞,用于进程同步
int xie = getpid();
printf("进程%d写入共享存储区:%d\n",getpid(),xie);
*addr= xie;
消息缓冲队列:
自定义消息数据结构:
struct msgform //消息结构
{
long mtype

最低0.47元/天 解锁文章
1356

被折叠的 条评论
为什么被折叠?



