前言

课程设计开始了,实验很有意思,写博客总结学到的知识
白嫖容易,创作不易,学到东西才是真
本文原创,创作不易,转载请注明!!!
本文链接
个人博客:https://ronglin.fun/archives/175
PDF链接:见博客网站
CSDN: https://blog.csdn.net/RongLin02/article/details/118308512

为了美观,实验源代码在结尾处,整合版见下
链接:https://pan.baidu.com/s/1rXj1QJGuw-BVc5sQWret9w
提取码:Lin2
操作系统课程设计源代码
本次操作系统课程设计合集
操作系统课设之Windows 进程管理
操作系统课设之Linux 进程管理
操作系统课设之Linux 进程间通信
操作系统课设之Windows 的互斥与同步
操作系统课设之内存管理
操作系统课设之虚拟内存页面置换算法的模拟与实现
操作系统课设之基于信号量机制的并发程序设计
操作系统课设之简单 shell 命令行解释器的设计与实现
仅用于学习,如有侵权,请联系我删除

实验题目

Linux 进程间通信

实验目的

Linux 系统的进程通信机构(IPC)允许在任意进程间大批量地交换数据,通过本实验,理解熟悉 Linux 支持的消息通信机制。

实验内容

实验原理:主要用到4个函数

int msgget(key_t key, int msgflag);

key:某个消息队列的名字,用ftok()产生 (函数ftok的返回值)或IPC_PRIVATE,获取消息队列的标识符,创建和访问一个消息队列。

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

msqid:消息队列标识符,由msgget获得;
cmd:控制标识符,IPC_SET 命令:设置属主的用户标识符和组标识符,IPC_STAT 和 IPC_INFO 命令:获得资源状态信息,IPC_RMID 命令:释放这个资源;
buf:消息队列管理结构体,请参见消息队列内核结构说明部分。

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

msqid:消息队列标识符;
msgp:发送给队列的消息。msgp可以是任何类型的结构体,但第一个字段必须为long类型,即表明此发送消息的类型,msgrcv根据此接收消息。msgp定义的参照格式如下:

    struct s_msg{ /*msgp定义的参照格式*/
     long type; /* 必须大于0,消息类型 */
           char mtext[256]; /*消息正文,可以是其他任何类型*/
    } msgp;

msgsz:要发送消息的大小,不含消息类型占用的4个字节,即mtext的长度;
msgflg:控制位,规定当核心用尽内部缓冲空间时应执行的动作

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);

msqid:消息队列标识符;
msgp:存放消息的结构体,结构体类型要与msgsnd函数发送的类型相同;
msgsz:要接收消息的大小,不含消息类型占用的4个字节;
msgtyp:0:接收第一个消息;>0:接收类型等于msgtyp的第一个消息;<0:接收类型等于或者小于msgtyp绝对值的第一个消息;
msgflg:规定倘若该队列无消息,核心应当做什么事,如果此时设置了 IPC_NOWAIT 标志,则
立即返回,若在 flag 中设置了 MSG_NOERROR,且所接收的消息大小大于 size ,核心截断所接收的消息。
msgrcv()解除阻塞的条件有以下三个:
1.消息队列中有了满足条件的消息。
2.msqid代表的消息队列被删除。
3.调用msgrcv()的进程被信号中断。
用以上4个函数实现Linux系统下的通信。

实验步骤:
在Linux虚拟机下,用codeblocks新建一个project,将指导书的代码copy到main.cpp文件下,多次运行查看结果。
关键代码如下:

#define MSGKEY 75
struct 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);
    }
    exit(0);
}
void SERVER()
{
    msgqid=msgget(MSGKEY,0777|IPC_CREAT);
    do
    {
        msgrcv(msgqid,&msg,1030,0,0);
        printf("(Server) recieved\n");
    }
    while(msg.mtype!=1);
    msgctl(msgqid,IPC_RMID,0);
    exit(0);
}
int main()
{
    while((i=fork())==-1);
    if(!i) SERVER();
    while((i=fork())==-1);
    if(!i) CLIENT();
    wait(0);wait(0);
    return 0;
}

四、实验结果与分析
运行结果如下:
在这里插入图片描述
多次结果运行结果均为上,只有极少数运行结果是client发送一条server接受一条。
对于以上结果,查阅资料可知:
message的传送和控制并不保证完全同步,当一个程序不再激活状态的时候,它完全可能继续睡眠,造成上面现象,在多次send message后才receive message.这一点有助于理解消息转送的实现机理。
消息通信的特点:消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。消息的传递,自身就带有同步的控制.当等到消息的时候,进程进入睡眠状态,不再消耗CPU资源。

小结与心得体会

由于main函数两次fork(),最开始我认为server也会fork()出client子进程,也就是,我认为作为子进程的server还会生成”孙”进程,但是多次运行调试后,结果并不是我想的那样,单步调试加测试输出之后,我发现了 exit(0),它在子函数里边,也就是说在执行完server()/client()子函数之后,子进程直接结束,不再返回main()函数。
对于Linux进程通信,之前了解的比较少,只是听说过管道的概念。这次验证实验了解了Linux进程间通信的基本方法,获益匪浅。
=w=

源代码

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <unistd.h>
#include<sys/wait.h>
#define MSGKEY 75
struct msgform
{
    long mtype;
    char mtext[1030];
} msg;
int msgqid,i;
void CLIENT()
{
    int i;
    //flag 本身由操作允许权和控制命令值相“或”得到。
    msgqid=msgget(MSGKEY,0777);
    for (i=10; i>=1; i--)
    {
        msg.mtype=i;
        printf("(client) sent \n");
        //flag 规定当核心用尽内部缓冲空间时应执行的动作
        msgsnd(msgqid,&msg,1024,0);
    }
    exit(0);
}
void SERVER()
{
    //IPC_CREAT | 0400 是否该队列应被创建;
    msgqid=msgget(MSGKEY,0777|IPC_CREAT);
    do
    {
        //type 是用户要读的消息类型:
        msgrcv(msgqid,&msg,1030,0,0);
        printf("(Server) recieved\n");
    }
    while(msg.mtype!=1);
    msgctl(msgqid,IPC_RMID,0);
    exit(0);
}
int main()
{
    while((i=fork())==-1);
    if(!i)
        SERVER();
    while((i=fork())==-1);
    if(!i)
        CLIENT();
    wait(0);
    wait(0);
    return 0;
}

GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐