【MIT6.828】【LAB Utilities 2】pingpong

【MIT6.828】【LAB Utilities 2】pingpong


前言

编写一个程序,使用UNIX系统调用,通过一对管道在两个进程之间“乒乓”一个字节,每个方向一个字节。父级通过向parent_fd[1]写入字节来发送,而子级通过从parent_fd[0]读取字节来接收。从父级接收到一个字节后,子级通过写入child_fd[1]以自己的字节进行响应,然后由父级读取。您的答案应该在user/pingpong.c文件中。


提示

  1. 使用pipe、fork、write,read。

实现

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"

int
main(int argc, char *argv[])
{
    int child_fd[2], parent_fd[2];
    char buf[1];
    pipe(child_fd);
    pipe(parent_fd);
    int pid = fork();
    if (pid == 0) {
        close(child_fd[0]);
        close(parent_fd[1]);
        read(parent_fd[0], buf, sizeof(buf));
        close(parent_fd[0]);
        fprintf(2,"%d: received ping\n", getpid());
        write(child_fd[1], "x", sizeof("x"));
        close(child_fd[1]);
    } else {
        close(parent_fd[0]);
        close(child_fd[1]);
        write(parent_fd[1], "x", sizeof("x"));
        close(parent_fd[1]);
        read(child_fd[0], buf, sizeof(buf));
        close(child_fd[0]);
        fprintf(2,"%d: received pong\n", getpid());
    }
    exit(0);
}

结果

$ make qemu
riscv64-unknown-elf-gcc -Wall -Werror -O -fno-omit-frame-pointer -ggdb -gdwarf-2 -MD -mcmodel=medany -ffreestanding -fno-common -nostdlib -mno-relax -I. -fno-stack-protector -fno-pie -no-pie   -c -o user/pingpong.o user/pingpong.c
riscv64-unknown-elf-ld -z max-page-size=4096 -T user/user.ld -o user/_pingpong user/pingpong.o user/ulib.o user/usys.o user/printf.o user/umalloc.o
riscv64-unknown-elf-objdump -S user/_pingpong > user/pingpong.asm
riscv64-unknown-elf-objdump -t user/_pingpong | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$/d' > user/pingpong.sym
mkfs/mkfs fs.img README user/_cat user/_echo user/_forktest user/_grep user/_init user/_kill user/_ln user/_ls user/_mkdir user/_rm user/_sh user/_stressfs user/_usertests user/_grind user/_wc user/_zombie user/_sleep user/_pingpong
nmeta 46 (boot, super, log blocks 30 inode blocks 13, bitmap blocks 1) blocks 1954 total 2000
balloc: first 808 blocks have been allocated
balloc: write bitmap block at sector 45
qemu-system-riscv64 -machine virt -bios none -kernel kernel/kernel -m 128M -smp 3 -nographic -global virtio-mmio.force-legacy=false -drive file=fs.img,if=none,format=raw,id=x0 -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0

xv6 kernel is booting

hart 1 starting
hart 2 starting
init: starting sh
$ pingpong
4: received ping
3: received pong
$

总结

通过这个实验加深了对pipe,fork,read,write的理解。
fork非常神奇,从代码当前行程序进入两个线程同时执行,在父进程内pid为子进程pid,子进程内为0,通过这一特征我们的程序判断当前程序执行在哪个进程中。
pipe会打开一个通道,使得不同进程间可以通信,其会生成一对文件描述符,一段读一段写。
在第一次实现的时候理解错了题目的意思,在父进程和子进程中利用两个pipe同时收发,得到了如下结果。

$ make qemu
qemu-system-riscv64 -machine virt -bios none -kernel kernel/kernel -m 128M -smp 3 -nographic -global virtio-mmio.force-legacy=false -drive file=fs.img,if=none,format=raw,id=x0 -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0

xv6 kernel is booting

hart 1 starting
hart 2 starting
init: starting sh
$ pingpong
34::  rerceeivecd epiinvge
d pong
$

因为笔者参考了网上其他博客的代码,又对比了lab里给的结果,思考为什么参考的代码中没有使用wait来避免并行,又想到lab的提示里并没有提示使用wait,发现理解错了题目意思。
同时可以得出结论,使用write,read在不同进程中操作pipe出的同一对文件描述符时是存在一定时序的。而操作不同的文件描述符对是并行的。
同时学到了fd在不用的时候尽量关闭,且使用完后尽快关闭。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值