linux system programming n.
Skip this Video
Loading SlideShow in 5 Seconds..
Linux System Programming PowerPoint Presentation
Download Presentation
Linux System Programming

Loading in 2 Seconds...

  share
play fullscreen
1 / 26
Download Presentation

Linux System Programming - PowerPoint PPT Presentation

clara
211 Views
Download Presentation

Linux System Programming

- - - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

  1. Linux System Programming Lecture #11 –공유메모리(Shared Memory)

  2. 공유메모리(Shared Memory) (1) • 공유메모리 정의 : • 두 개이상의 프로세스가 실제 메모리의 일부를 공유하여 통신할 수 있는 IPC 도구 • 통신하려는 프로세스는 우선 공유 메모리를 할당받는다 • 프로세스는 할당된 공유 메모리를 자신의 가상주소공간 일부에 붙여(attach) 메모리에 데이터를 읽고 쓰는 것가 동일한 방법으로 필요한 데이터를 읽거나 전송하려는 데이터를 기록하여 상호 통신한다 • 프로세스간의 통신이 종료되면 공유 메모리를 가상주소공간에서 떼어내고(detach) 공유 메모리를 해제한다 • IPC 도구 중에서 가장 효율적 • 시스템 간의 이식성이 낮음 • 프로세스간의 메모리 공유를 위해 별도의 하드웨어 지원이 필요 • 공유 메모리를 사용한 프로그램을 하드웨어 지원이 없는 시스템에서는 사용불가 Linux System Programming

  3. 공유메모리(Shared Memory) (2) • 공유 메모리 시스템 호출 : • shmget –공유 메모리를 새롭게 할당하거나 할당된 공유 메모리의 핸들을 반환한다 • shmctl –공유 메모리와 관련된 상태 변수값을 변경하거나 공유 메모리를 제거한다 • shmat –공유 메모리를 프로세스의 가상주소공간에 논리적으로 부착(attach)한다 • shmdt –프로세스의 가상주소공간으로부터 공유 메모리를 분리한다 Linux System Programming

  4. shmget() 프로세스 P1 프로세스 P2 공유메모리 shmat() shmat() shmdt() shmdt() 가상주소: 10000 가상주소: 20000 shmctl() 공유메모리(Shared Memory) (3) • 공유 메모리 시스템 호출 : Linux System Programming

  5. 공유메모리(Shared Memory) (4) • 공유 메모리의 생성: shmget() Linux System Programming

  6. 공유메모리(Shared Memory) (5) • 공유 메모리의 생성: shmget() • 공유 메모리 구조체 Linux System Programming

  7. 공유메모리(Shared Memory) (6) • 공유 메모리의 생성: shmget() • 공유 메모리 구조체의 초기화 Linux System Programming

  8. 공유메모리(Shared Memory) (7) • 공유 메모리의 제어: shmctl() Linux System Programming

  9. 공유메모리(Shared Memory) (8) • 공유 메모리의 제어: shmctl() • shmctl 시스템 호출의 명령어 Linux System Programming

  10. 공유메모리(Shared Memory) (9) • 공유 메모리의 연산: shmat()/shmdt() Linux System Programming

  11. 예제 프로그램 (1) • 예제 11-1 • 학원 강좌 예약 시스템 프로그램 • 부모 프로세스는 강좌 예약 정보를 갖는 공유 메모리을 할당하고, 공유 메모리에 대한 상호배제를 위한 세마포어를 생성한다 • 자식 프로세스을 생성하여 강좌 예약을 수행하는데, 자식 프로세스는 주기적으로 강좌 예약을 수행하도록 시뮬레이션하며, 더 이상 예약할 좌석(seat)가 없으면 종료한다 • 부모 프로세스는 모든 자식 프로세스가 종료할 때까지 기다렸다가 세마포어와 공유 메모리를 제거하고 종료한다 Linux System Programming

  12. 예제 프로그램 (2) // // file name: ex11-1.h // struct CLASS { char class_number[6]; char date[6]; char title[50]; int seats_left; } typedef struct CLASS class_t; Linux System Programming

  13. 예제 프로그램 (3) // file name: ex11-1a.c // #include <stdio.h> #include <memory.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <sys/shm.h> #include "ex11-1.h" class_t class = { "1001", "120186", "C Language for Programmers", 15 }; #define NCHILD 3 int child[NCHILD]; char *shm_ptr, *shmat(); int semid, shmid; char ascsemid[10], ascshmid[10]; char pname[14]; void rpterror(); int main(int argc, char *argv[]) { int i; Linux System Programming

  14. 예제 프로그램 (4) strcpy(pname, argv[0]); shm_init(); sem_init(); for(i=0; i < NCHILD; i++) { child[i] = fork(); switch(child[i]) { case -1: rpterror("fork-failure"); exit(1); case 0: sprintf(pname,"ex11-1b%d",i+1); execl("ex11-1b", pname, ascshmid, ascsemid, (char *) 0); perror("execl faild"); exit(2); } } wait_and_wrap_up(); } shm_init() { shmid=shmget(IPC_PRIVATE, sizeof(class), 0600|IPC_CREAT); if(shmid == -1) { perror("shmget failed"); exit(3); } shm_ptr = shmat(shmid, (char *) 0, 0); if(shm_ptr == (char *) -1) { perror("shmat failed"); exit(4); } memcpy(shm_ptr,(char *) &class, sizeof(class)); sprintf(ascshmid,"%d", shmid); } Linux System Programming

  15. 예제 프로그램 (5) sem_init() { if((semid=semget(IPC_PRIVATE, 1, 0600| IPC_CREAT)) == -1) { perror("semget failed"); exit(5); } if((semctl(semid, 0, SETVAL,1)) == -1) { printf("parent: semctl, SETVAL failed\n"); exit(6); } sprintf(ascsemid,"%d",semid); } wait_and_wrap_up() { int wait_rtn, w, ch_active = NCHILD; while(ch_active > 0) { wait_rtn = wait((int *) 0); for(w=0; w < NCHILD; w++) if(child[w] == wait_rtn) { ch_active--; break; } } printf("Parent removing shm and sem\n"); shmdt(shm_ptr); shmctl(shmid, IPC_RMID); semctl(semid, 0, IPC_RMID, 0); exit(0); } Linux System Programming

  16. 예제 프로그램 (6) void rpterror(string) char *string; { char errline[50]; sprintf(errline,"%s %s",string, pname); perror(errline); } Linux System Programming

  17. 예제 프로그램 (7) // file name: ex11-1b.c // #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <sys/shm.h> #include "ex11-1.h" class_t *class_ptr; char *memptr, *shmat(), *pname; int semid, shmid, ret; struct sembuf lock = { 0, -1, 0}; struct sembuf unlock = { 0, 1, 0}; void rpterror(); int main(int argc, char *argv[]) { if(argc < 3) { fprintf(stderr, "Usage: %s shmid semid\n", argv[0]); exit(1); } pname = argv[0]; sscanf(argv[1],"%d", &shmid); memptr = shmat(shmid, (char *) 0, 0); Linux System Programming

  18. 예제 프로그램 (8) if(memptr == (char *) -1) { rpterror("shmat failed"); exit(2); } class_ptr = (class_t *) memptr; sscanf(argv[2], "%d", &semid); sell_seats(); ret = shmdt(memptr); exit(0); } sell_seats() { int all_out = 0; srand((unsigned) getpid()); while(! all_out) { /* loop to sell all seats */ if(semop(semid, &lock, 1) == -1) { rpterror("semop lock failed"); exit(4); } if(class_ptr -> seats_left > 0) { class_ptr -> seats_left--; printf("%s SOLD SEAT -- %2d left\n", pname, class_ptr->seats_left); } Linux System Programming

  19. 예제 프로그램 (9) else { all_out++; printf("%s sees no seats left\n", pname); } ret = semop(semid, &unlock, 1); if(ret ==-1) { rpterror("semop unlock failed"); exit(4); } sleep((unsigned) rand() %10 +1); } } void rpterror(string) char *string; { char errline[50]; sprintf(errline,"%s %s",string, pname); perror(errline); } Linux System Programming

  20. 예제 프로그램 (10) • 예제 11-2 • 세마포어와 공유 메모리를 이용하여 버퍼의 자료를 생산하고 소비하는 생산자/소비자(producer/consumer) 프로그램 • 생산자는 공유 메모리를 할당하여 버퍼를 설정한다 • 생산자와 소비자 사이에 버퍼 접근을 위한 동기화를 위해 2 개의 세마포어를 생성하여 사용한다 • 버퍼 쓰기 동기화(consumed 동기화) - 생산자는 소비자가 버퍼의 자료를 읽고 간 후에 새로운 자료를 버퍼에 쓴다 • 버퍼 읽기 동기화(produced동기화) - 소비자는 생산자가 버퍼에 새로운 자료를 쓴 후에 자료를 읽어간다 Linux System Programming

  21. 예제 프로그램 (11) // file name: ex11-2a.c // /* producer program: producer program sets up a buffer to be read by a consumer. semaphore are used to ensure taht producer dosen't overwrite an unread buffer and consumer dosen't read the same data more than once. */ #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <sys/shm.h> #define MSG_SIZE 30 #define MAX 5 main() { char *getenv(); key_t ftok(); char *shmat(); key_t key; void perror(), exit(); Linux System Programming

  22. 예제 프로그램 (12) /* two semaphores in a set index 0 - incremented when producer has reset buffer - tested and decremented by consumer to check if buffer has been reset index 1 - incremented when consumer has read buffer - tested and decremented by producer to check if consumer is done. */ static struct sembuf wait_consumed = { 1, -1, 0}; static struct sembuf signal_produced = { 0, 1, 0}; int semid, shmid; char *message; int i; if((key = ftok(getenv("HOME"), 'u')) == (key_t) -1) { fprintf(stderr,"ftok key formation error\n"); exit(1); } semid = semget(key, 2, IPC_CREAT | 0660); if(semid == -1) { perror("producer semget():"); exit(2); } Linux System Programming

  23. 예제 프로그램 (13) shmid = shmget(key, MSG_SIZE, IPC_CREAT | 0660); if(semid == -1) { perror("producer shmget():"); exit(3); } message = shmat(shmid, (char *) 0, 0); for(i=1; i < MAX; i++) { /* producer has to go first */ if(i>1) semop(semid, &wait_consumed, 1); sprintf(message, "message %d", i); semop(semid, &signal_produced, 1); } shmdt(message); sleep(5); /* allow consumer to digest last message */ /* alternatively a DELIMITER string could be placed in shared memory when seen by the consumer, it would exit. the producer would do shmctl (..., IPC_STAT, ....) and when shm_attach == 1, it would remove the two IPC facilities */ shmctl(shmid, IPC_RMID, (struct shmid_ds *) 0); shmctl(shmid, 0, IPC_RMID); } Linux System Programming

  24. 예제 프로그램 (14) // file name: ex11-2b.c // /* consumer program: producer program sets up a buffer to be read by a consumer. semaphore are used to ensure taht producer dosen't overwrite an unread buffer and consumer dosen't read the same data more than once. */ #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <sys/shm.h> #define MSG_SIZE 30 int main(int argc, char *argv[]) { /* two semaphores in a set index 0 - incremented when producer has reset buffer - tested and decremented by consumer to check if buffer has been reset index 1 - incremented when consumer has read buffer - tested and decremented by producer to check if consumer is done. */ Linux System Programming

  25. 예제 프로그램 (15) key_t key; static struct sembuf wait_produced = { 0, -1, 0}; static struct sembuf signal_consumed = { 1, 1, 0}; int semid, shmid; char *message; int rtn; if((key = ftok(getenv("HOME"), 'u')) == (key_t) -1) { fprintf(stderr,"ftok key formation error\n"); exit(1); } /* either producer or consumer might be the creator but producer will be the remover of IPC resources. producer and consumer's effective uid must be the same. */ semid = semget(key, 2, IPC_CREAT | 0660); if(semid == -1) { perror("producer semget():"); exit(2); } Linux System Programming

  26. 예제 프로그램 (16) shmid = shmget(key, MSG_SIZE, IPC_CREAT | 0660); if(semid == -1) { perror("producer shmget():"); exit(3); } message = shmat(shmid, (char *) 0, SHM_RDONLY); while(1) { rtn = semop(semid, &wait_produced, 1); /* when producer is done semid will be IPC_RMID forcing break */ if(rtn == -1) { perror("consumer - semop on wait_consumed"); break; } printf("%s recevied: %s\n", argv[0], message); semop(semid, &signal_consumed, 1); } shmdt(message); } Linux System Programming