공유 메모리[1] 공유 메모리 공유 메모리 생성: shmget(2) 같은 메모리 공간을 두 개 이상의 프로세스가 공유하는 것

Slides:



Advertisements
Similar presentations
YES C 제 1 장 C 언어의 개요 1/34 제 1 장 C 언어의 개요 문봉근. YES C 제 1 장 C 언어의 개요 2/34 제 1 장 C 언어의 개요 1.1 프로그램과 C 언어의 특징 1.2 C 언어의 프로그램 구성 1.3 비주얼 C++ 통합 환경 들어가기.
Advertisements

Linux System Programming
제 3 장 변수와 자료형.
Linux/UNIX Programming APUE (The Environment of a UNIX Process)
리눅스 시스템 프로그래밍 고 영 웅.
Task 통신 및 동기화 : Message Queue, Semaphore Shared Memory
Department of Computer Engineering
9 파이프.
인공지능실험실 석사 2학기 김승겸 TCP/IP Socket Programming… 제 10장 멀티태스킹 기반의 서버구현 인공지능실험실 석사 2학기 김승겸
Signal & Inter-Process Communication
디바이스 드라이버 기초 디바이스 드라이버의 개요 파일 연산 디바이스 드라이버 등록 디바이스 드라이버 구성
디바이스 드라이버 개요 가상 디바이스드라이버 실습
Department of Computer Engineering
쉽게 풀어쓴 C언어 Express 제17장 동적 메모리와 연결 리스트 C Express.
쉽게 풀어쓴 C언어 Express 제4장 변수와 자료형 C Express.
제5장 제어명령
Multi-thread Programming
6 프로세스 생성과 실행.
6 프로세스 생성과 실행.
Linux System Programming
6장 비연결형 지향 프로토콜 Database Lab 강 우 석.
제 12장 I/O멀티플렉싱(Multiplexing)
7. while 문의 흐름 제어.
FND (Flexible Numeric Display)
쉽게 풀어쓴 C언어 Express 제17장 동적메모리와 연결리스트 C Express.
Department of Computer Engineering
데이터베이스 실험실 석사 2학기 김기훈 TCP/IP Socket Programming… 제 17장 멀티쓰레드 기반의 서버구현 데이터베이스 실험실 석사 2학기 김기훈
Department of Computer Engineering
시스템 V IPC 기초[1] 시스템 V IPC 공통 요소 키 생성
10 시스템V의 프로세스간 통신.
Linux System Programming
C 9장. 구조체 #include <stdio.h> int main(void) { int num;
10 시스템V의 프로세스간 통신.
양방향 파이프의 활용 양방향 통신 파이프는 기본적으로 단방향이므로 양방향 통신을 위해서는 파이프를 2개 생성한다.
fork로 생성한 자식 프로세스에서 exec 함수군을 호출
멀티쓰레드 기반의 서버구현 School of Electronics and Information.
운영체제 허상복 컴퓨터시스템 연구실
10장 포인터와 문자열 포인터 기본 배열과 포인터 매개변수 전달방법 포인터와 문자열.
링크 파일 생성[1] 링크 하드링크 생성 : link(2) 이미 있는 파일이나 디렉토리에 접근할 수 있는 새로운 이름
Term Project Team Member
프로세스 생성[1] 프로그램 실행 : system(3) #include <stdlib.h>
파일 기술자 복사 파일 기술자 복사 : dup(2) 파일 기술자 복사 : dup2(3)
Linux/UNIX Programming APUE (Interprocess Communication)
Advanced Socket Programming
6장 파일 및 레코드 잠금.
메시지 큐[5] – test1.c 메시지 제어: msgctl(2) #include <sys/msg.h>
Department of Computer Engineering
파일 접근권한 제어 stat 구조체의 st_mode 항목에 파일의 종류와 접근권한 정보저장 st_mode 값의 구조.
10장 C 표준 파일 입출력 子曰 學而時習(실습?)之 不亦悅乎.
5 프로세스 정보.
쉽게 풀어쓴 C언어 Express 제4장 변수와 자료형 C Express.
4장 제어문 선택문: if 문, if – else 문, switch 문
쉽게 풀어쓴 C언어 Express 제4장 변수와 자료형 C Express.
adopted from KNK C Programming : A Modern Approach
Signal & Inter-Process Communication
Memory & Data Management.
컴퓨터의 기초 제 2강 - 변수와 자료형 , 연산자 2006년 3월 27일.
Analog to Digital Converter
컴퓨터 프로그래밍 기초 - 4th : 수식과 연산자 -
제어문 & 반복문 C스터디 2주차.
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
Fflush 사용이유 및 방법 [이유] 키보드에서 입력된 내용은 입력버퍼에 저장되었다가 Enter 키가 들어오면 프로그램으로 전달됨 이 때 입력버퍼에 있는 Enter 키도 프로그램으로 전달됨 그러므로 아래와 같은 프로그램에서 문자 하나를 입력해도 Enter키도 입력된 것으로.
6장 반복제어문 for 문 while 문 do while 문 기타 제어문.
Department of Computer Engineering
쉽게 풀어쓴 C언어 Express 제6장 조건문 C Express Slide 1 (of 28)
쉽게 풀어쓴 C언어 Express 제6장 조건문 C Express.
실습과제 1번 생성된 파일 basic.txt를 프로젝트 폴더에서 메모장으로 열고 내용을 확인
9 파이프.
Signal & Inter-Process Communication
C 13장. 입출력 라이브러리 #include <stdio.h> int main(void) { int num;
Presentation transcript:

공유 메모리[1] 공유 메모리 공유 메모리 생성: shmget(2) 같은 메모리 공간을 두 개 이상의 프로세스가 공유하는 것 같은 메모리 공간을 사용하므로 이를 통해 데이터를 주고 받을 수 있음 공유 메모리 생성: shmget(2) key : IPC_PRIVATE 또는 ftok로 생성한 키값 size : 공유할 메모리 크기 shmflg : 공유 메모리의 속성을 지정하는 플래그 IPC_CREAT, IPC_EXCL 공유 메모리 식별자를 리턴(shmid_ds 구조체) #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> int shmget(key_t key, size_t size, int shmflg);

공유 메모리[2] shmid_ds 구조체 struct shmid_ds { struct ipc_perm msg_perm; size_t shm_segsz; struct anon_map *shm_amp; pid_tt_t shm_lpid;; pid_t shm_cpid; shmatt_t shm_nattch; ulong_t shm_cnattch; time_t shm_atime; int32_t shm_pad1; time_t shm_dtime; int32_t shm_pad2; time_t shm_ctime; int32_t shm_pad3; int32_t shm_pad4[4]; }; shm_perm: IPC공통 구조체 shm_segsz: 공유 메모리 세그먼트 크기 shm_lpid: 마지막으로 shmop동작을 한 프로세스ID shm_cpid : 공유 메모리를 생성한 프로세스ID shm_nattach: 공유 메모리를 연결하고 있는 프로세스 수 shm_atime: 마지막으로 공유 메모리를 연결한 시각 shm_dtime: 마지막으로 공유 메모리 연결을 해제한 시각 shm_ctime: 마지막으로 공유 메모리 접근 권한을 변 경한 시각

[예제 10-4] 공유 메모리 생성하기(test1.c) ... 07 int main(void) { 08 key_t key; 09 int shmid; 10 key = ftok("shmfile", 1); 12 shmid = shmget(key, 1024, IPC_CREAT|0644); 13 if (shmid == -1) { 14 perror("shmget"); 15 exit(1); 16 } 17 18 return 0; 19 } 키 생성 공유 메모리 생성. # ex10_4.out # ipcs -mo IPC status from <running system> as of 2009년 2월 18일 수요일 오후 03시 06분 01초 T ID KEY MODE OWNER GROUP NATTCH Shared Memory: m 0 0x100719b --rw-r--r-- root other 0

공유 메모리[3] 공유 메모리 연결: shmat(2) 공유 메모리 연결 해제: shmdt(2) shmid : 공유 메모리 식별자 shmaddr : 공유 메모리를 연결할 주소 shmflg : 공유 메모리에 대한 읽기/쓰기 권한 0(읽기/쓰기 가능), SHM_RDONLY(읽기 전용) 공유 메모리 연결 해제: shmdt(2) shmaddr: 연결을 해제힐 공유 메모리 주소 #include <sys/types.h> #include <sys/shm.h> void *shmat(int shmid, const void *shmaddr, int shmflg); #include <sys/types.h> #include <sys/shm.h> int shmdt(char *shmaddr);

공유 메모리[4] 공유 메모리 제어: shmctl(2) #include <sys/types.h> cmd : 수행할 제어기능 IPC_RMID : 공유 메모리 제거 IPC_SET : 공유 메모리 정보 내용 중 shm_perm.uid, shm_perm.gid, shm_perm.mode 값을 세번째 인자로 지정한 값으로 변경 IPC_STAT : 현재 공유 메모리의 정보를 buf에 지정한 메모리에 저장 SHM_LOCK : 공유 메모리를 잠근다. SHM_UNLOCK : 공유 메모리의 잠금을 해제한다. #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> int shmctl(int shmid, int cmd, struct shmid_ds *buf);

[예제 10-5] 공유 메모리 사용하기 부모/자식 프로세스 간 공유 메모리 사용 예제 ... ex10_5.c 부모/자식 프로세스 간 공유 메모리 사용 예제 ... 09 int main(void) { 10 int shmid, i; 11 char *shmaddr, *shmaddr2; 12 13 shmid = shmget(IPC_PRIVATE, 20, IPC_CREAT|0644); 14 if (shmid == -1) { 15 perror("shmget"); 16 exit(1); 17 } 18 19 switch (fork()) { 20 case -1: 21 perror("fork"); 22 exit(1); 23 break; 공유 메모리 생성

[예제 10-5] 공유 메모리 사용하기 (test2.c) 24 case 0: 25 shmaddr = (char *)shmat(shmid, (char *)NULL, 0); 26 printf("Child Process =====\n"); 27 for (i=0; i<10; i++) 28 shmaddr[i] = 'a' + i; 29 shmdt((char *)shmaddr); 30 exit(0); 31 break; 32 default: 33 wait(0); 34 shmaddr2 = (char *)shmat(shmid, (char *)NULL, 0); 35 printf("Parent Process =====\n"); 36 for (i=0; i<10; i++) 37 printf("%c ", shmaddr2[i]); 38 printf("\n"); 39 sleep(5); 40 shmdt((char *)shmaddr2); 41 shmctl(shmid, IPC_RMID, (struct shmid_ds *)NULL); 42 break; 43 } 44 45 return 0; 46 } 공유 메모리 연결 공유메모리에 데이터 기록 후 공유 메모리 연결 해제 공유 메모리 연결 공유 메모리 내용 출력 공유 메모리 연결 해제 공유 메모리 삭제 # ex10_5.out Child Process ===== Parent Process ===== a b c d e f g h i j

[예제 10-6] (1) listener (서버역할) – server.c 독립적인 프로세스 간 공유 메모리 사용 예제 ... 10 void handler(int dummy) { 11 ; 12 } 13 14 int main(void) { 15 key_t key; 16 int shmid; 17 void *shmaddr; 18 char buf[1024]; 19 sigset_t mask; 20 21 key = ftok("shmfile", 1); 22 shmid = shmget(key, 1024, IPC_CREAT|0666); 23 24 sigfillset(&mask); 25 sigdelset(&mask, SIGUSR1); 26 sigset(SIGUSR1, handler); 27 28 printf("Listener wait for Talker\n"); 키 생성 공유 메모리 생성 시그널 처리 지정

[예제 10-6] (1) listener (서버역할) ex10_6s.c 29 sigsuspend(&mask); 30 31 printf("Listener Start =====\n"); 32 shmaddr = shmat(shmid, NULL, 0); 33 strcpy(buf, shmaddr); 34 printf("Listener received : %s\n", buf); 35 36 strcpy(shmaddr, "Have a nice day\n"); 37 sleep(3); 38 shmdt(shmaddr); 39 40 return 0; 41 } 시그널 올 때까지 대기 시그널이 오면 공유 메모리 연결 메모리 내용 읽고 출력 공유 메모리에 쓰기

[예제 10-6] (2) talker(클라이언트 역할)-client.c ... 11 int main(int argc, char **argv) { 12 key_t key; 13 int shmid; 14 void *shmaddr; 15 char buf[1024]; 16 17 key = ftok("shmfile", 1); 18 shmid = shmget(key, 1024, 0); 19 20 shmaddr = shmat(shmid, NULL, 0); 21 strcpy(shmaddr, "Hello, I'm talker\n"); 22 23 kill(atoi(argv[1]), SIGUSR1); 24 sleep(2); 25 strcpy(buf, shmaddr); 26 27 printf("Listener said : %s\n", buf); 28 system("ipcs -mo"); 29 shmdt(shmaddr); 30 shmctl(shmid, IPC_RMID, NULL); 31 32 return 0; 33 } 서버와 같은 키 생성 공유 메모리 정보 가져오기 공유 메모리 연결하고 데이터 기록 시그널 발송 서버가 보낸 메시지 읽어 출력 공유 메모리 연결 해제 및 삭제

[예제 10-6] 실행결과 # listener & [1] 4946 # Listener wait for Talker [1] 4946 # Listener wait for Talker Listener Start ===== Listener received : Hello, I'm talker # talker 4946 Listener said : Have a nice day IPC status from <running system> as of 2009년 2월 18일 수요일 오후 07시 53분 12초 T ID KEY MODE OWNER GROUP NATTCH Shared Memory: m 4 0x100719b --rw-rw-rw- root other 2 # ipcs IPC status from <running system> as of 2009 년 2월 18일 수요일 오후 07시 53분 57초 T ID KEY MODE OWNER GROUP Message Queues: Semaphores:

실습 두 프로그램이 같은 공유 메모리에 문자열(UNIX, PROGRAMMING)을 쓰고 읽는 프로그램을 작성하라. 문자열은 읽고 쓰기를 10번 반복하도록 한다. 공유 메모리에 문자열을 기록하고 다시 읽어 출력하기 전에 sleep(1)을 실행한다

세마포어[1] 세마포어 세마포어 기본 동작 구조 프로세스 사이의 동기를 맞추는 기능 제공 한 번에 한 프로세스만 작업을 수행하는 부분에 접근해 잠그거나, 다시 잠금을 해제하는 기능을 제공하는 정수형 변수 세마포어를 처음 제안한 에츠허르 데이크스트라가 사용한 용어에 따라 잠금함수는 p로 표시하고 해제함수는 v로 표시 세마포어 기본 동작 구조 중요 처리부분(critical section)에 들어가기 전에 p 함수를 실행하여 잠금 수행 처리를 마치면 v 함수를 실행하여 잠금 해제 p(sem); // 잠금 중요한 처리 부분 v(sem); // 잠금 해제

세마포어[2] p 함수의 기본 동작 구조 v 함수의 기본 동작 구조 p(sem) { while sem=0 do wait; } v(sem) { sem 값을 1 증가; if (대기중인 프로세스가 있으면) 대기중인 첫 번째 프로세스를 동작시킨 }

세마포어[3] 세마포어 생성: semget(2) semid_ds 구조체 #include <sys/types.h> nsems : 생성할 세마포어 개수 semflg : 세마포어 접근 속성 (IPC_CREAT, IPC_EXCL) semid_ds 구조체 #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> int semget(key_t key, int nsems, int semflg); struct semid_ds { struct ipc_perm sem_perm; struct sem *sem_base; ushort_t sem_nsems; time_t sem_otime; int32_t sem_pad1; time_t sem_ctime; int32_t sem_pad2; int sem_binary; long sem_pad3[3]; }; sem_perm: IPC공통 구조체 sem_base: 세마포어 집합에서 첫번째 세마포어의 주소 sem_nsems: 세모포어 집합에서 세마포어 개수 sem_otime: 세마포어 연산을 수행한 마지막시간 sem_ctime: 세마포어 접근권한을 마지막으로 변경 한 시간 sem_binary: 세마포어 종류를 나타내는 플래그

세마포어[4] sem 구조체 세마포어 정보를 저장하는 구조체 struct sem { ushort_t semval; pid_t sempid; ushort_t semncnt; ushort_t semzcnt; kcondvar_t semncnt_cv; kcondvar_t semzcnt_cv; }; semval : 세마포어 값 sempid : 세마포어 연산을 마지막으로 수행한 프로 세스 PID semncnt: 세마포어 값이 현재 값보다 증가하기를 기다리는 프로세스 수 semzcnt: 세마포어 값이 0이 되기를 기다리는 프로 세스 수

세마포어[5] 세마포어 제어: semctl(2) cmd에 지정할 수 있는 값 semnum : 기능을 제어할 세마포어 번호 cmd : 수행할 제어 명령 ... : 제어 명령에 따라 필요시 사용할 세마포어 공용체 주소(선택사항) cmd에 지정할 수 있는 값 IPC_RMID, IPC_SET, IPC_STAT : 메시지 큐, 공유 메모리와 동일 기능 GETVAL : 세마포어의 semval 값을 읽어온다. SETVAL : 세마포어의 semval 값을 arg.val로 설정한다. GETPID : 세마포어의 sempid 값을 읽어온다. GETNCNT, GETZNCNT : 세마포어의 semncnt, semzcnt 값을 읽어온다. GETALL : 세마포어 집합에 있는 모든 세마포어의 semval 값을 arg.array에 저장 SETALL : 세마포어 집합에 있는 모든 세마포어의 semval 값을 arg.array의 값으로 설정 #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> int semctl(int semid, int semnum, int cmd, ...); union semun { int val; struct semid_df * buf; ushort_t *array; } arg;

세마포어[6] 세마포어 연산: semop(2) 세마포어 연산 #include <sys/types.h> sops : sembuf 구조체 주소 nsops : sops가 가리키는 구조체 크기 세마포어 연산 sembuf 구조체의 sem_op 항목에 지정 #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> int semop(int semid, struct sembuf *sops, size_t nsops); struct sembuf { ushort_t sem_num; short sem_op; short sem_flg; }; 세마포어 연산을 의미 if (sem_op < 0) { /* 세마포어 잠금 */ wait until semval >= | sem_op |; semval -= | sem_op |; } else if (sem_op > 0) /* 세마포어 잠금 해제 */ semval += sem_op; else wait until semval is 0;

세마포어[7] sem_op가 음수 : 세마포어 잠금 기능 수행 semval 값이 sem_op의 절댓값과 같거나 크면 semval 값에서 sem_op의 절댓값을 뺀다. semval 값이 sem_op 값보다 작고 sem_flg에 IPC_NOWAIT가 설정되어 있으면 semop 함수는 즉시 리턴 semval 값이 sem_op 값보다 작은데 sem_flg에 IPC_NOWAIT가 설정되어 있지 않으면 semop 함수는 semncnt 값을 증가시키고 다음 상황을 기다린다. semval 값이 sem_op의 절대값보다 같거나 커진다. 이 경우 semncnt 값은 감소하고 semval 값에서 sem_op의 절대값을 뺀다. 시스템에서 semid가 제거된다. 이 경우 errno가 EIDRM으로 설정되고 -1을 리턴한다. semop 함수를 호출한 프로세스가 시그널을 받는다. 이 경우 semncnt 값은 감소하고 시그널 처리함수를 수행한다. sem_op가 양수면 이는 세마포어의 잠금을 해제하고 사용중이던 공유자원을 돌려준다. 이 경우 sem_op 값이 semval 값에 더해진다. sem_op 값이 0일 경우 semval 값이 0이면 semop 함수는 즉시 리턴한다. semval 값이 0이 아니고, sem_flg에 IPC_NOWAIT가 설정되어 있으면 semop 함수는 즉시 리턴한다. semval 값이 0이 아니고, sem_flg에 IPC_NOWAIT가 설정되어 있지 않으면 semop 함수는 semzcnt 값을 증가시키고 semval 값이 0이 되길 기다린다.

[예제 10-7] (1) 세마포어 생성과 초기화 (test3.c) ... 09 union semun { 10 int val; struct semid_ds *buf; 12 unsigned short *array; 13 }; 14 15 int initsem(key_t semkey) { 16 union semun semunarg; 17 int status = 0, semid; 18 19 semid = semget(semkey, 1, IPC_CREAT | IPC_EXCL | 0600); 20 if (semid == -1) { 21 if (errno == EEXIST) 22 semid = semget(semkey, 1, 0); 23 } 24 else { 25 semunarg.val = 1; 26 status = semctl(semid, 0, SETVAL, semunarg); 27 } 28 29 if (semid == -1 || status == -1) { 30 perror("initsem"); 31 return (-1); 32 } 33 34 return semid; 35 } semun 공용체 선언 세마포어 생성 및 초기화 함수 세마포어 생성 세마포어 값을 1로 초기화

sem_op 값을 양수로 하여 잠금해제기능 수행 [예제 10-7] (2) 세마포어 연산 36 37 int semlock(int semid) { struct sembuf buf; 39 40 buf.sem_num = 0; 41 buf.sem_op = -1; 42 buf.sem_flg = SEM_UNDO; 43 if (semop(semid, &buf, 1) == -1) { 44 perror("semlock failed"); 45 exit(1); 46 } 47 return 0; 48 } 49 50 int semunlock(int semid) { 51 struct sembuf buf; 52 53 buf.sem_num = 0; 54 buf.sem_op = 1; 55 buf.sem_flg = SEM_UNDO; 56 if (semop(semid, &buf, 1) == -1) { 57 perror("semunlock failed"); 58 exit(1); 59 } 60 return 0; 61 } 세마포어 잠금 함수 sem_op 값을 음수로 하여 잠금기능 수행 세마포어 잠금 해제 함수 sem_op 값을 양수로 하여 잠금해제기능 수행

[예제 10-7] (3) 세마포어 호출 63 void semhandle() { 64 int semid; 65 pid_t pid = getpid(); 66 67 if ((semid = initsem(1)) < 0) 68 exit(1); 69 70 semlock(semid); 71 printf("Lock : Process %d\n", (int)pid); 72 printf("** Lock Mode : Critical Section\n"); 73 sleep(1); 74 printf("Unlock : Process %d\n", (int)pid); 75 semunlock(semid); 76 77 exit(0); 78 } 79 80 int main(void) { 81 int a; 82 for (a = 0; a < 3; a++) 83 if (fork() == 0) semhandle(); 84 85 return 0; 86 } 세마포어 생성 함수 호출 세마포어 잠금함수 호출 처리부분 세마포어 잠금 해제 함수 호출 자식 프로세스를 3개 만든다.

[예제 10-7] 실행결과 세마포어 기능을 사용하지 않을 경우 세마포어 기능을 사용할 경우 # ex10_7.out Lock : Process 5262 ** Lock Mode : Critical Section Lock : Process 5263 Lock : Process 5264 Unlock : Process 5263 Unlock : Process 5262 Unlock : Process 5264 5262 프로세스가 처리부분을 실행하는 중에 다른 프로세스도 같이 수행된다. # ex10_7.out Lock : Process 5195 ** Lock Mode : Critical Section Unlock : Process 5195 Lock : Process 5196 Unlock : Process 5196 Lock : Process 5197 Unlock : Process 5197 5262 프로세스가 처리부분을 실행하는 중에 다른 프로세스는 실행하지 않고 차례로 실행한다.

실습 주어진 test4.c에 semaphore을 추가하여 수정하라