MIT XV6 - 1.2 Lab: Xv6 and Unix utilities - pingpong

接上文 MIT XV6 - 1.1 Lab: Xv6 and Unix utilities - user/_sleep 是什么?做什么?

pingpong

不务正业了那么久(然而并没有,虽然还在探索sleep,但是教材我已经看完了前三章了),让我们赶紧继续下去

在进行本实验之前请务必阅读完教材 Chapter 1,尤其是1.3对于PIPE的介绍,实验具体要求如下:

Write a user-level program that uses xv6 system calls to ''ping-pong'' a byte between two processes over a pair of pipes, one for each direction. The parent should send a byte to the child; the child should print "pid : received ping", where pid is its process ID, write the byte on the pipe to the parent, and exit; the parent should read the byte from the child, print "pid: received pong", and exit. Your solution should be in the file user/pingpong.c.
Some hints:

  • Add the program to UPROGS in Makefile.
  • Use pipe to create a pipe.
  • Use fork to create a child.
  • Use read to read from a pipe, and write to write to a pipe.
  • Use getpid to find the process ID of the calling process.
  • User programs on xv6 have a limited set of library functions available to them. You can see the list in user/user.h; the source (other than for system calls) is in user/ulib.c, user/printf.c, and user/umalloc.c.
    Run the program from the xv6 shell and it should produce the following output:
bash 复制代码
make qemu
...
init: start sh
$ pingpong
4: received ping
3: received pong
$

整体还是比较简单的,主要你得理解forkpipe的用法,以及一些要点,比如fork的返回值如果是子进程,那么会返回0;read会一直等到有足够的输入或者文件描述符被关闭啊。这些都在课本中有描述。

以下是实验源码(这注释,不用想,一定是AI写的...) GitHub已经同步

c 复制代码
/*
 * pingpong.c - A simple program demonstrating inter-process communication using pipes
 * 
 * This program creates a parent-child process pair that communicate through a pipe.
 * The parent sends a "ping" message to the child, and the child responds with a "pong".
 * 
 * Communication Flow:
 * 1. Parent creates a pipe
 * 2. Parent forks a child process
 * 3. Both processes have access to the pipe's read and write ends
 * 4. Parent writes "p" to pipe and waits for response
 * 5. Child reads "p" from pipe, prints "received ping", and writes "p" back
 * 6. Parent reads "p" from pipe and prints "received pong"
 * 
 * Timing Diagram:
 * 
 * Parent Process          Child Process
 *     |                       |
 *     |--pipe creation------>|
 *     |                       |
 *     |--fork()------------->|
 *     |                       |
 *     |--write("p")--------->|
 *     |                       |
 *     |<--read("p")----------|
 *     |                       |
 *     |<--write("p")---------|
 *     |                       |
 *     |--read("p")---------->|
 *     |                       |
 *     |--wait()------------->|
 *     |                       |
 *     |<--exit()-------------|
 *     |                       |
 */

#include "kernel/types.h"  // Include kernel type definitions
#include "user/user.h"     // Include user-level system call definitions

int main(int argc, char *argv[]) {
  int p[2];                // Array to store pipe file descriptors
  pipe(p);                 // Create a pipe, p[0] for reading, p[1] for writing
  
  char buf[1];            // Buffer to store single character messages
  
  if (fork() == 0) {      // Child process
    read(p[0], buf, 1);   // Read "p" from parent
    printf("%d: received ping\n", getpid());  // Print child's PID and message
    write(p[1], "p", 1);  // Send "p" back to parent
    close(p[0]);          // Close read end
    close(p[1]);          // Close write end
    exit(0);              // Exit child process
  } else {                // Parent process
    write(p[1], "p", 1);  // Send "p" to child
    read(p[0], buf, 1);   // Wait for child's response
    printf("%d: received pong\n", getpid());  // Print parent's PID and message
    wait(0);              // Wait for child to exit
    close(p[0]);          // Close read end
    close(p[1]);          // Close write end
    exit(0);              // Exit parent process
  }
  return 0;
}

实验结果

bash 复制代码
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
4: received ping
3: received pong
$ QEMU: Terminated

ut结果

bash 复制代码
./grade-lab-util pingpong
make: `kernel/kernel' is up to date.
== Test pingpong == pingpong: OK (1.1s) 

我觉得得找时间看看他ut都做了什么。

相关推荐
sulikey10 小时前
个人Linux操作系统学习笔记2 - gcc与库的理解
linux·笔记·学习·操作系统·gcc·
一枝小雨13 小时前
RISC-V架构sp寄存器 & RISC-V架构下FreeRTOS任务上下文保存与恢复
单片机·架构·嵌入式·risc-v·rtos·内核原理
手可摘星辰的少年18 小时前
Ext2文件系统核心结构详解:超级块、位图、Inode与多级间接块
操作系统
一枝小雨19 小时前
RISC-V架构的中断与异常处理机制学习笔记
单片机·架构·嵌入式·risc-v·内核原理·中断与异常
星马梦缘20 小时前
操作系统实验5 —— 进程互斥
linux·操作系统·进程互斥
iCxhust21 小时前
从裸机到微内核:8088单板机微型操作系统规划设计
操作系统·课程设计·微机原理·8086最小系统·8088单板机
一枝小雨21 小时前
什么是标准C函数:以RISC-V架构下的C函数为例
c语言·risc-v·内核原理
咕咚.萌西2 天前
RISCV AS汇编器
risc-v
磊 子2 天前
1.2内存的存储金字塔
java·开发语言·spring·操作系统
sulikey2 天前
Linux ext2文件系统结构
linux·操作系统·文件系统·linux文件系统·ext2·ext2文件系统