操作系统实验三、进程通信

操作系统实验三、进程通信

一、实验目的

​ 1、了解和熟悉Linux支持的消息通信机制、管道道通信、共享存储区机制及信息量机制。

2、掌握利用Linux系统的进程通信机制(IPC)实现进程间交换数据的方法。

二、实验内容

​ 1、进程通信

​ 使用系统调用pipe()建立一条管道线:两个子进程P1和P2分别向管道各写一句话:

​ Child 1 is sending a message!

​ Child 2 is sending a message!

​ 父进程则从管道中读出来自两个了进程的信息,显示在屏幕上。

要求父进程先接收子进程P1发来的消息,然后再接收子进程P2发来的消息。(可以通过sleep()将自身进入睡眠)

2、 消息的创建,发送和接收.

​ (1) 使用系统调用msgget(), msgsnd(), msgsrv()及msgctl()编制一长度为1K的消息(如个人通信录信息)的发送和接收程序.

   (2) 使用共享存储区相关的系统调用 shmget(),shmat(),sgmdt(),shmctl(),编制一个与上述功能相同的程序.

​ (3) 比较上述两种消息通信机制中数据传输的时间。

三、设计原理(或方案)及相关算法

  1. 管道通信 创建一条管道,子进程写入数据,父进程写出数据。在父进程中使用 wait() 函数,这样在子进程执行 完毕之前,父进程一直要等待。

    调用pipe()建立一条管道,两个子进程分别向管道写入一句话,在父进程中使用wait()函数,使父进程等待子进程执行结束,依次输出P1、P2发来的消息。

  2. 消息的创建,接受和发送

    (1)消息队列通信 设计一个结构体来充当缓冲区,存储消息。之后使用msgget(), msgsnd(), msgsrv()及msgctl() 等函数来 实现消息的发送和接受。

    (2)使用shmget(),shmat(),sgmdt(),shmctl()等函数实现存储区的共享,轮流使用存储区来接收、发送消息

四、结果分析

image-20211114203951486

2.1

image-20211114204211269

2.2

image-20211114204630674

五、源代码

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>

void main()
{
    pid_t pid_1, pid_2, fd[2];
    char buf[50], s[50];
    pipe(fd);

    while ((pid_1 = fork()) == -1)
        ;
    if (pid_1 == 0)
    {
        lockf(fd[1], 1, 0);
        sprintf(buf, "Child 1 is sending message");
        write(fd[1], buf, 50);
        lockf(fd[1], 0, 0);
        exit(0);
    }
    else
    {
        while ((pid_2 = fork()) == -1);
        if (pid_2 == 0)
        {
            lockf(fd[1], 1, 0);
            sprintf(buf, "Child 2 is sending message");
            write(fd[1], buf, 50);
            lockf(fd[1], 0, 0);
            exit(0);
        }
        else
        {
            wait(0);
            read(fd[0], s, 50);
            printf("%s \n", s);
            wait(0);
            read(fd[0], s, 50);
            printf("%s \n", s);
            exit(0);
        }
    }
}

2.1

#include<stdio.h>
#include<sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#define MSGKEY 75

struct msgform{
    long mtype;
    char mtext[1024];
}msg;
int msgqid,i;
void CLIENT(){
    int i;
    msgqid = msgget(MSGKEY,0777|IPC_CREAT);
    for(i=10;i>=1;i--){
        msg.mtype=i;
        printf("(client)send\n");
        msgsnd(msgqid,&msg,1024,0);
    }
    exit(0);
}
void SERVER(){
    msgqid = msgget(MSGKEY,0777|IPC_CREAT);
    do{
        msgrcv(msgqid,&msg,1024,0,0);
        printf("(server)receive\n");
    }while(msg.mtype!= 1);
    msgctl(msgqid,IPC_RMID,0);
}

int main(){
    if(fork()){
        SERVER();
        wait(0);
    } else {
        CLIENT();
    }
    
    return 0;
}

2.2

#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#define SHMKEY 75

int shmid ,i;
int *addr;


void CLIENT(){
    int i;
    shmid = shmget(SHMKEY,1024,0777|IPC_CREAT);
    addr = shmat(shmid,0,0);
    for(i=9;i>=0;i--){
        while (*addr != -1);
        printf("(client)send\n");
        *addr = i;
    }
    exit(0);
}

void SERVER(){
   
    do{
        while ( *addr == -1);
        printf("(server)receive\n");
        if(*addr != 0)
            *addr = -1;
    }while(*addr);
    wait(0);
    shmctl(shmid,IPC_RMID,0);
}

int main(){
    shmid = shmget(SHMKEY,1024,0777|IPC_CREAT);
    addr = shmat(shmid,0,0);
    *addr = -1;
    if(fork()){
        SERVER();
        wait(0);
    } else {
        CLIENT();
    }

    return 0;
}

  • 7
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值