MIT 6.828 - 1. Lab 01: Xv6 and Unix utilities - pingpong
문제 (Problems)
pingpong (easy)
Write a program that uses UNIX 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:
- 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.
- Add the program to UPROGS in Makefile.
- 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:
$ make qemu
...
init: starting sh
$ pingpong
4: received ping
3: received pong
$
Your solution is correct if your program exchanges a byte between two processes and produces output as shown above.
코드(Code) - pingpong.c 파일
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
int main(int argc, char *argv[])
{
int parent_fd[2], child_fd[2]; //parent, child file descriptor
char get_buf[128]; //Receive pingpong message
pipe(parent_fd); //create pipe
pipe(child_fd);
if (fork() == 0) //child
{
close(parent_fd[1]);
read(parent_fd[0], get_buf, 4); //read 4bytes
close(parent_fd[0]);
printf("%d: received %s\n", getpid(), get_buf);
close(child_fd[0]);
write(child_fd[1], "pong", 4);
close(child_fd[1]);
}
else //parent
{
close(parent_fd[0]);
write(parent_fd[1], "ping", 4);
close(parent_fd[1]);
close(child_fd[1]);
read(child_fd[0], get_buf, 4); //read 4bytes
close(child_fd[0]);
printf("%d: received %s\n", getpid(), get_buf);
}
exit();
}
로직(logic) 설명
부모와 자식 프로세스의 파이프 file descriptor을 받기 위한 변수 parent_fd와 child_fd를 생성하고, write값을 받기 위한 변수 get_buf를 생성한다.
pipe는 기본적으로 one-way 단방향 통신이기 때문에 pipe를 2개 생성함으로써 양방향 통신이 가능하도록 한다.
Pipe를 2개 생성한 후에 fork( )를 함으로써 자식 프로세스도 부모 프로세스의 pipe를 가지도록 한다. fork( ) == 0 일 때, 그러니까 자식프로세스일 때는 부모 프로세스가 읽고(read), 자식 프로세스가 쓰기(write)를 한다. 부모 프로세스가 읽을 때 부모가 쓰는 것을 방지하기 위해 close(parent_fd[1]); 을 해준다. 그리고 read가 끝나면 close(parent_fd[0]); 을 해주어 파이프를 닫는다. 자식 프로세스는 4bytes 만큼을 사용해 “pong”을 write한다.
마찬가지로 부모 프로세스일 때는 부모 프로세스가 “ping”을 4bytes만큼 write를 하고, 자식 프로세스는 get_buf에서 read를 한다.
이렇게 부모 프로세스와 자식 프로세스가 pipe 2개와 file descriptor 4개를 가지고 양방향 통신을 하는 pipe를 구현한다.
구현 결과(Result)
'TIL > OS & Linux' 카테고리의 다른 글
MIT 6.828 - 1. Lab 01: Xv6 and Unix utilities - xargs 코드 및 해석 (0) | 2022.11.05 |
---|---|
MIT 6.828 - 1. Lab 01: Xv6 and Unix utilities - find 코드 및 해석 (0) | 2022.11.05 |
MIT 6.828 - 1. Lab 01: Xv6 and Unix utilities - sleep 코드 및 해석 (0) | 2022.11.05 |
[Linux] 리눅스 기본 명령어 모음 / 자주 쓰는 리눅스 명령어 정리 (1) | 2022.09.21 |
댓글