Download presentation
Presentation is loading. Please wait.
1
리눅스 커널의 이해 중에서 18장. 프로세스 통신 김상국 네트워크 실험실
2
목차 Part I : PIPE & FIFO Part II : SYSTEM V IPC
3
프로세스간 통신을 위한 방법 IPC 방법 = IPC 객체 프로세스 프로세스 시그널 파이프 FIFO 세마포어 메시지 큐
공유메모리 커널에 의해 생성
4
Part I : PIPE & FIFO
5
파이프 사용하기 $ ls | more pipe() 호출 (fd3 -> read, fd 4 -> write)
fork() 2회 호출 close() 2회 호출 dup2(4,1) 호출 -> pipe write close() 두번 호출(fd3,4 해제) execve() 호출(/bin/ls 실행) -> fd 1(표준출력)에 출력 dup2(3,0) 호출 -> pipe read close() 두번 호출(fd3,4 해제) execve() 호출(/bin/more실행) -> fd 0(표준입력)에 입력
6
$ ls | more => $ ls > temp
$ more < temp <장점> - shell 문장이 더 짧고, 간단 - 임시 파일을 생성하고, 나중에 삭제할 필요 없음 <단점> - open된 파이프에 대해서 open 할 수 없음(관련성 없는 프로세스간에 데이터 전송할 수 없음)
7
파이프 자료구조 base start lock Page Frame Addr 저장 read(), write() call
Process 1 Process 2 file file f_mode f_mode f_pos f_pos f_flags f_flags f_count f_count f_owner f_owner f_inode f_inode f_op f_op Page Frame Addr 저장 f_version inode f_version read(), write() call inode & file 1,2 생성 read와 write 위함 파일 디스크림터 사용 U field Pipe_inode_info base start lock : Pipe Write Operations Pipe Read Operations
8
파이프 생성과 제거 pipe() <- sys_pipe() 제공 do_pipe() 호출 base start lock
Process 1 Process 2 1. Pipe read 위해 파일 객체와 fd 할당 > f_flag<- O_RDONLY > f_op <- Read_pipe_fops 초기화 2. Pipe write 위해 파일 객체와 fd 할당 > f_flag<- O_WRDONLY > f_op <-write_pipe_fops 초기화 file file f_mode f_mode f_pos f_pos f_flags f_flags f_count f_count f_owner f_owner f_inode f_inode f_op f_op f_version inode 3. get_pipe_inode() 호출 >inode 할당 & 초기화 >pipe 버퍼 위한 page frame 할당 & 주소 -> base필드에 저장 f_version 4. 디엔트리 객체 할당하고 이것으로 두 파일과 inde 연결(12장 참조) 5. 두 파일 디스크립터를 유저 모드 프로 세스에 반환 U Pipe_inode_info base start lock : Pipe Write Operations Pipe Read Operations I_size
9
파이프에서 읽기 데이터를 얻고자 하는 프로세스는 read() 시스템 콜을 호출하면서 파이프의 읽기 채널과 관련한 디스크립터를 파일 디스크립터로 지정 Pipe_read()의 연산 수행 1. inode의 i_size 필드에 저장된 파이프 크기가 ‘0’인지 검사 2. Pipe_inode_info 자료 구조의 lock 필드 검사, ‘o’이 아니면 현재 다른 프로세스가 접근한 상태(현재 프로세스 보류 또는 즉시 종료) 3. lock 필드를 증가 4. 요청한 바이트 수를 파이프 버퍼에서 사용자 주소 공간으로 복사 5. Lock 필드를 감소 6. Wake_up_interruptible() 호출, 파이프의 대기 큐에서 잠들고 있는 모든 프로세스를 깨움 7. 사용자 주소 공간으로 복사한 바이트 수를 반환
10
파이프에 쓰기 데이터를 파이프에 넣으려는 프로세스는 write() 시스템 콜을 호출하면서 파이프의 쓰기 채널과 관련한 디스크립터를 파일 디스크립터로 지정 Pipe_write()의 연산 수행 1. 읽기 프로세스가 하나라도 있는지 검사 또는 SIGPIPE 시그널을 current 프로세스에 보내고, -EPIPE 값을 반환 2. 파이프의 inode에서 i_sem 세마포어를 해제 (I_sem 세마포어는 sys_write()로 얻음) 3. 쓰려는 바이트 수 검사 (작으면 워자성 만족, 크면 연산 가능, 빈 바이트 = ‘1’인지 검사) 4. 요청한 바이트 수를 파이프 버퍼에서 사용자 주소 공간으로 복사 5. Pipe_inode_info 자료 구조의 lock 필드 검사 (‘0’이 아니면 다른 프로세스가 읽는중 ->블록킹/넌블록킹 체크하여 보류/중지)
11
파이프에 쓰기 Pipe_write()의 연산 수행 6. lock 필드를 증가
7. 요청한 바이트 수를 사용자 주소 공간에서 파이프의 버퍼로 복사 8. 아직 쓰지 못한 바이트가 남아 있으면, 4단계로 리턴 9. 모든 요청한 데이터를 쓴 다음, lock 필드를 감소 10. Wake_up_interruptible() 호출, 파이프의 대기 큐에서 잠들고 있는 모든 프로세스를 깨움 11. i_atomic_write 세마포어를 해제, i_sem 세마포어를 얻음 (sys_write()가 i_sem 세마포어를 해제할 수 있도록) 12. 파이프의 버퍼에 쓴 바이트 수를 반환
12
FIFO(or named PIPE) 연산과 구조는 PIPE와 거의 동일하나 부모자식 프로세스 관계처럼 조산이 같은 프로세스간에서만 채널 가능 필요에 의해 생성되고 파이프를 생성한 프로세스가 종료시 소멸되는 단점을 보완하기위해 도입된 IPC 기법 파이프가 사용상의 편의성과 간단함을 주는 반면 이미 열려져 있는 pipe에 대해서는 open할 수 없다는 것 -> 즉, 서로 관련성을 가지지 않는 프로세스간에는 데이터를 전송할 수 없음(FIFO는 inode구조를 제공하여 해결) FIFO를 사용한 디바이스 노드 생성 방법 -> mknod(), mkfifo(0<성공> or –1<에러>)
13
Part II : System V IPC II-1. Semaphore II-2. Message
II-3. Shared Memory
14
System V IPC Summary of System V IPC system calls
kernel은 각 IPC channel에 대해서도 file을 다루기 위한 정보와 비슷한 정보의 구조를 갖음 <sys/ipc.h>에 정의 이 구조를 사용하고 변경하기 위해서는 세 가지의 ctl system call을 사용 하나의 IPC channel을 만들거나 열기위해 사용
15
System V IPC의 3가지 유형 System V IPC 3가지 유형의 공통특성(common properties)
Key => id 커널에서 ***id_ds라는 자료구조 생성(eg: msqid_ds) 접근제어(ipc_perm):key, uid, cuid, access mode, … IPC 관련 명령어: ipcs, ipcrm, … System V IPC 3가지 유형의 차이점 Semaphore : task 간 동기화에 이용(11장 참고) Message : 객체 지향 개념에 적합 Shared Memory : 빠르다
16
Semaphore 정의 프로세스간에 중요한 데이터 접근에 있어, 서로 간에 접근하는 순서를 정함
연결리스트에 자료접근시, 임의의 프로세스 2개가 동시에 접근할 경우 하나의 프로세스가 자료구조를 고치는 도중에 스케줄링 아웃되어 있다면 다른 프로세스가 실행될 기회를 얻게되어, 같은 자료구조를 고칠 경우 다시 원래 프로세스가 실행되어 재 시작시 자료구조는 깨짐 이진 세마포어를 사용(0과 1을 사용하여 변수에 저장) “1”경우 접근 허용, 아닌 경우 대기(wait) 접근할 수 있다면 “0”으로 set, 연산 후 “1”로 set 변수에 대한 테스트 증가, 커널의 활동 등 보호되어야 한번에 이 모든 연산이 끝나야 함(atomic)
17
Semaphore 정의 Process 간의 데이터 교환 방식이 아님 공유 데이터의 접근에 필요한 동기화의 제공
☞ 주로 사용하는 곳은 shared memory segment에 접근을 동기화 하기위함 접근 단계 ☞ 자원의 접근을 제어하는 세마포어 값을 확인 ☞ 세마포어 값이 0보다 크면 프로세서는 자원을 사용 가능 - 대신 세마포어의 값은 하나 감소하여 현재 자원이 사용중임을 표시 ☞ 세마포어 값이 0보다 작으면 그 값이 0보다 커질 때 까지 sleep 상태로 기다림 ☞ 프로세스가 깨어나면 1단계부터 다시 진행 세마포어는 2진을 사용하고 1로 초기화
18
Message 정의 프로세스간 통신에 있어 IPC 메시지를 사용하여 통신
Byte의 연속(메시지에 들어 있는 내용은 관여하지 않음) 프로세스는 메시지를 보낼 수도 있고, 메시지 큐로부터 메시지를 받을 수 있음 큐(Queue) : 메시지가 들어간 순서대로 메시지 큐로부터 하나씩 꺼냄 고정 길이의 헤더와 가변 길이의 텍스트로 이루어짐 메시지는 정수값으로 라벨을 붙일 수 있음(message.type) 이를 사용하여 프로세스는 메시지 큐에서 메시지를 선택하여 읽음 프로세스가 IPC 메시지 큐에서 메시지 큐를 읽으면, 커널은 메시지를 삭제 함 따라서 한 프로세스만 메시지를 받을 수 있음
19
Shared Memory 정의 IPC의 여러 형태 중 가장 빠름
이유 : 다른 프로세스가 사용하는 메모리 영역에 대해 직접 접근하여 읽거나 씀 단, 프로세스는 반드시 동기적으로 원하는 메모리에 접근해야 함 특정한 번호를 공유되는 부분에 대한 ID로 사용 이 번호는 shmid_ds 구조체를 가리키는 역할을 함 공유디는 메모리에 대해서는 attach와 detach 연산을 했다면, 프로세스내에 그 메모리 영역이 있다고 생각하면 됨
20
Presemaphore undo list
Semaphore & Memory & Shared Memory의 차이점 sem_ids ipc(_id(kern_ipc_perm struct) = Sem_array(semid_ds)의 첫부분 (ipc_ids struct) size key NULL NULL NULL in_use uid max_id gid (semaphore struct) seq cuid seq_max count cgid sem sleepers mode ary wait seq entries 1 SEMMNI ipc_addid() continued p sem_ctime sem_base sem_pending sem_pending_last undo sem_nsems struct_sem struct sem_queue id_next sem_array(semid_ds) struct의 나머지 부분 Pending Request Queue Presemaphore undo list NULL next/prev shm_segsz shm_atime shm_dtime shm_ctime shm_cpid shm_lpid shm_nattch shm_unusedx shm_file id shm_cbytes shm_cprid shm_lprid shm_perm Ipc_addid() 함수 File Object (f_op = shm_file_operation; mmap()) inode Object (i_ino = shmid_kernel -> id) msg_stime msg_rtime msg_ctime msg_cbytes msg_qnum msg_qbytes msg_lspid msg_lrpid _unusedx msgid_ds의 나머지 부분 g_stime q_rtime q_ctime q_cbytes q_qnum q_qbytes q_lspid q_lrpid q_messages q_perm q_receivers q_senders list tsk g_lrpid r_task r_mode r_msgtype r_maxsize r_msg r_list Ipc_addr() 함수 msg_receiver msg_msg msg_sender msg_queue Shared Memory Semaphore Message
21
Part III : Reference Add-on Linux Kernel Programming
Interprocess Communication in Linux UNIX Network Programming 리눅스 프로그래머를 위한 가이드 임근수, 범용 운영체제 구현을 위한 리눅스 커널 완전 분석
Similar presentations