打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
OS Lab 1.3 pingpong (easy)
1
实验要求

    使用 UNIX 系统调用编写一个程序 pingpong ,在一对管道上实现两个进程之间的通信。父进程应该通过第一个管道给子进程发送一个信息 "ping",子进程接收父进程的信息后打印 "<pid>: received ping" ,其中是其进程 ID 。然后子进程通过另一个管道发送一个信息 "pong" 给父进程,父进程接收子进程的信息然后打印 "<pid>: received pong" ,然后退出。

2
实验提示

  • 使用 pipe 创建管道。
  • 使用 fork 创建一个子进程。
  • 使用 read 从管道读取信息,使用 write 将信息写入管道。
  • 使用 getpid 获取当前 进程 ID 。
  • 将程序添加到 Makefile 中的 UPROGS 。
  • xv6 上的用户程序具有有限的库函数可供它们使用。你可以在 user/user.h 中查看,除系统调用外其他函数代码位于 user/ulib.c 、user/printf.c 、和 user/umalloc.c 中。

3
实验思路

  1. 首先引入头文件 kernel/types.h 和 user/user.h 。
  2. 开始编写 main 函数,定义两个文件描述符 ptoc_fd 和 ctop_fd 数组,创建两个管道, pipe(ptoc_fd) 和 pipe(ctop_fd) ,一个用于父进程传递信息给子进程,另一个用于子进程传递信息给父进程。pipe(pipefd) 系统调用会创建管道,并把读取和写入的文件描述符返回到 pipefd 中。pipefd[0] 指管道的读取端, pipefd[1] 指管道的写入端。可以使用命令 man pipe 查看手册获取更多内容。
  3. 创建缓冲区字符数组,存放传递的信息。
  4. 使用 fork 创建子进程,子进程的 fork 返回值为 0 ,父进程的 fork 返回子进程的 进程 ID ,所以通过 if 语句就能让父进程和子进程执行不同的代码块。
  5. 编写父进程执行的代码块。使用 write() 系统调用传入三个参数,把字符串 "ping" 写入管道一,第一个参数为管道的写入端文件描述符,第二个参数为写入的字符串,第三个参数为写入的字符串长度。然后调用 wait() 函数等待子进程完成操作后退出,传入参数 0 或者 NULL ,不过后者需要引入头文件 stddef.h 。使用 read() 系统调用传入三个参数,接收从管道二传来的信息,第一个参数为管道的读取端文件描述符,第二个参数为缓冲区字符数组,第三个参数为读取的字符串长度。最后调用 printf() 函数打印当前进程 ID 以及接收到的信息,即缓冲区的内容。
  6. 编写子进程执行的代码块。使用 read() 系统调用传入三个参数,接收从管道一传来的信息,第一个参数为管道的读取端文件描述符,第二个参数为缓冲区字符数组,第三个参数为读取的字符串长度。然后调用 printf() 函数打印当前进程 ID 以及接收到的信息,即缓冲区的内容。最后使用 write() 系统调用传入三个参数,把字符串 "pong" 写入管道二,第一个参数为管道的写入端文件描述符,第二个参数为写入的字符串,第三个参数为写入的字符串长度。
  7. 最后调用 exit() 系统调用使程序正常退出。

4
实验代码

// Lab Xv6 and Unix utilities
// pingpong.c
#include "kernel/types.h"
#include "user/user.h"
#include "stddef.h"

int
main(int argc, char *argv[])
{
    int ptoc_fd[2], ctop_fd[2];
    pipe(ptoc_fd);
    pipe(ctop_fd);
    char buf[8];
    if (fork() == 0) {
        // child process
        read(ptoc_fd[0], buf, 4);
        printf("%d: received %s\n", getpid(), buf);
        write(ctop_fd[1], "pong"strlen("pong"));
    }
    else {
        // parent process
        write(ptoc_fd[1], "ping"strlen("ping"));
        wait(NULL);
        read(ctop_fd[0], buf, 4);
        printf("%d: received %s\n", getpid(), buf);
    }
    exit(0);
}


5
实验结果

    在 Makefile 文件中, UPROGS 项追加一行 $U/_pingpong\ 。编译并运行 xv6 进行测试。
$ make qemu
...
init: starting sh
$ pingpong
4: received ping
3: received pong
$

退出 xv6 ,运行单元测试检查结果是否正确。

./grade-lab-util pingpong

通过测试样例。

make: 'kernel/kernel' is up to date.
== Test pingpong == pingpong: OK (1.1s)
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
pipe函数详解
进程间通信 | 管道通信Ⅰ
进程间8种通信方式详解
socketpair()函数介绍
dup和dup2函数
进程管道通信 - 多端写入lockf加锁
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服