1 / 24

운영체제 개론 및 실습

운영체제 개론 및 실습. 단국대학교 정보 컴퓨터학부 2007 년 4 월 최종무 choijm@dku.edu http://embedded.dankook.ac.kr/~choijm. kernel. kernel. struct msqid_ds. stack. stack. sending tasks. T. T. T. heap. heap. msg. msg. msg. data. data. text. shared memory. T. text. T. receiving tasks. IPC.

hafwen
Download Presentation

운영체제 개론 및 실습

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 운영체제 개론 및 실습 단국대학교 정보 컴퓨터학부 2007년 4월 최종무 choijm@dku.edu http://embedded.dankook.ac.kr/~choijm

  2. kernel kernel struct msqid_ds stack stack sending tasks T T T heap heap msg msg msg data data text shared memory T text T receiving tasks IPC • semaphore • memory에 접근하는 process들의 동기화 지원 • shared memory ? • process들이 memory를 공유하고 이를 통해 통신하는 기능을 지원 • message queue ? • process들 사이에 message를 주고 받는 기능을 지원

  3. IPC • System V IPC 3가지 유형의 공통점 • IPC 식별자(identifier) 사용 • IPC 객체에 접근하기 위해서는 식별자 필요 • Key를 identifier 로 매핑 (ftok) • 통신을 하려는 프로세스는 키를 공유해야 함 • 커널에 ***id_ds라는 자료 구조 생성 (eg: msqid_ds) • IPC 관련 명령어 제공: ipcs, ipcrm, ..

  4. IPC #include <sys/ipc.h> key_t ftok(const char *path, int id); • 파일의 경로명을 key로 변환 • 매개변수 • path : 경로명 • id : 임의의 정수 값

  5. 철학자들의 만찬 • Scenario • 각각의 철학자는 다른 철학자에게 말을 할 수 없다. • 철학자가 스파게티를 먹기 위해서는 양 옆의 포크를 동시에 들고 있어야 한다. • Problem • 교착 상태 • 에츠허트 데이크스트라의 해결책 • 각각의 철학자: p1,p2,p3,p4,p5 • 왼쪽 포크: f1,f2,f3,f4,f5 • p5를 제외한 네 명은 f n -> f n+1, p5는 f1->f5

  6. semaphore 제어 매개변수 semid : semget호출로 얻은 식별자 semnum : semaphore set의 원소 cmd : 연산의 종류 Semaphore Set #include <sys/sem.h> int semget(key_t key, int nsems, int semflg); • semaphore 생성 or 접근 • 매개변수 • key : 고유의 semaphore에 접근하기 위해 사용 • nsems : semaphore가 만들어 질 수 있는 크기(원소의 갯수) • semflg : 접근 권한 정의(생성자 1?, 소비자 0?) #include <sys/sem.h> int semctl(int semid, int semnum, int cmd, …);

  7. Semaphore Set #include <sys/sem.h> int semop(int semid, struct sembuf *sops, size_t nsops); • 사용자 정의 semaphore 연산을 원자적으로 수행 • 매개변수 • sops : 원소 연산의 배열 • nsops : 배열내의 원소 연산의 개수

  8. 예제 1(chainsemset.c) 1/5 • chainsemset.c int initelement(int semid, int semnum, int semvalue); int r_semop(int semid, struct sembuf *sops, int nsops); int removesem(int semid); void setsembuf(struct sembuf *s, int num, int op, int flg); void printerror(char *msg, int error); pid_t r_wait(int *stat_loc); int initelement(int semid, int semnum, int semvalue){ union semun{ int val; #include <errno.h> #include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/sem.h> #include <sys/stat.h> #include <sys/wait.h> #define BUFSIZE 1024 #define PERM (S_IRUSR | S_IWUSR)

  9. 예제 1(chainsemset.c) 2/5 struct semid_ds *buf; unsigned short *array; }arg; arg.val = semvalue; return semctl(semid, semnum, SETVAL, arg); } int r_semop(int semid, struct sembuf *sops, int nsops){ while(semop(semid, sops, nsops) ==-1) if(errno != EINTR) return -1; return 0; } void setsembuf(struct sembuf *s, int num, int op, int flg){ s->sem_num = (short)num; s->sem_op = (short)op; s->sem_flg = (short)flg; return; } void printerror(char *msg, int error){ fprintf(stderr, "[%ld] %s : %s \n", (long)getpid(), msg, strerror(error)); } pid_t r_wait(int *stat_loc){ int retval;

  10. 예제 1(chainsemset.c) 3/5 int error; int i, j, n; int semid; struct sembuf semsignal[1]; struct sembuf semwait[1]; if( (argc!=3) || ((n=atoi(argv[1]))<=0) || ((delay = atoi(argv[2]))<0) ){ fprintf(stderr, "Usage : %s processes delay\n", argv[0]); return 1; } if((semid= semget(IPC_PRIVATE, 1, PERM)) == 1){ while(((retval = wait(stat_loc)) == -1) && (errno == EINTR)); return retval; } int removesem(int semid){ return semctl(semid, 0, IPC_RMID); } int main(int argc, char *argv[]){ char buffer[BUFSIZE]; char *c; pid_t childpid; int delay;

  11. 예제 1(chainsemset.c) 4/5 for(i = 1; i<n; i++) if(childpid = fork()) break; snprintf(buffer, BUFSIZE, "i:%d PID:%ld parent PID:%d child PID:%ld\n", i, (long)getpid(), (long)getppid(), (long)childpid); c=buffer; if(((error= r_semop(semid, semwait, 1)) == -1)&& (i>1)){ printerror("Child failed to lock semid", error); return 1; } perror("Failed to crate a private semaphore"); return 1; } setsembuf(semwait, 0, -1, 0); setsembuf(semsignal, 0, 1, 0); if(initelement(semid, 0, 1) == -1){ perror("Failed to initialize semaphore element to 1"); if(removesem(semid) == -1) perror("Failed to remove failed semaphore"); return 1; }

  12. 예제 1(chainsemset.c) 5/5 if((r_wait(NULL) == -1) && (errno != ECHILD)) printerror("Failed to wait", errno); if((i==1) && ((error = removesem(semid)) == -1)){ printerror("Failed to clean up", error); return 1; } return 0; } else if(!error){ while(*c != '\0'){ fputc(*c, stderr); c++; for(j=0; j<delay;j++); } if((error = r_semop(semid, semsignal, 1)) == -1) printerror("Failed to unlock semid", error); }

  13. Shard Memory

  14. shard memory를 사용하기 위해 attach 매개변수 shmid : shmget호출로 얻은 식별자 shmaddr : 메모리가 attach될 주소 명시(보통 0) shmflg : read or write mode 지정 Shard Memory #include <sys/shm.h> int shmget(key_t key, size_t size, int shmflg); • kernel에 shard memory 공간을 요청 • 매개변수 • key : 고유의 공유메모리에 접근하기 위해 사용(공유메모리 구분) • size : 공유메모리의 최소 크기 • shmflg : 접근 권한과, 생성 방식 정의 #include <sys/shm.h> void shmat(int shmid, const void *shmaddr, int shmflg)

  15. Shard Memory #include < sys/shm.h> int shmdt(const void *shmaddr); • shard memory와 process를 detach • 매개변수 • shmaddr : 공유 메모리 세그먼트의 시작 주소 #include < sys/shm.h> int shmctl(int shmid, int cmd, struct shmid_ds *buf); • shard memory를 제어 하기 위해 사용 • 매개변수 • shmid : 식별자 • cmd : 제어 하고자 하는 내용 • IPC_RMID • IPC_SET • IPC_STAT • buf : cmd에 따라 다름

  16. Shard Memory #include < sys/shm.h> int shmctl(int shmid, int cmd, struct shmid_ds *buf); • shard memory와 process를 detach • 매개변수 • shmid : 식별자 • cmd : • sval = 0? • sval = -3?

  17. 예제2(shm_srv.c)1/2 // Attach the segment. if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) { perror("shmat"); exit(1); } // Put some things into the memory. s = shm; for (c = 'a'; c <= 'z'; c++) *s++ = c; *s = NULL; // We wait until the other process while (*shm != '*') sleep(1); exit(0); } #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <stdio.h> #include <stdlib.h> #define SHM_MAX_SIZE 256 main() { char c; int shmid; key_t key; char *shm, *s; // Create the key. key = ftok(".",1234); // Create the segment. if ((shmid = shmget(key, SHM_MAX_SIZE, IPC_CREAT | 0666)) < 0) { perror("shmget"); exit(1); }

  18. 예제2(shm_cli.c)2/2 18 // Attach the segment. if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) { perror("shmat"); exit(1); } // Read what the server put in the memory. for (s = shm; *s != NULL; s++) putchar(*s); putchar('\n'); // Change the first character of the segment to '*' *shm = '*'; exit(0); } #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <stdio.h> #include <stdlib.h> #define SHM_MAX_SIZE 256 main(){ int shmid; key_t key; char *shm, *s; // Create the key. key = ftok(".",1234); // Locate the segment. if ((shmid = shmget(key, SHM_MAX_SIZE, 0666)) < 0) { perror("shmget"); exit(1); }

  19. Message Queue IBM’s WebSphere MQ MSMQ(Microsoft Message Queuing)

  20. msg Q에 msg를 삽입 매개변수 msgid : 식별자 msgq : Q에 삽입 하고자 하는 msg의 포인터 msgsz : msg의 크기 msgflg : 여러 조건에서 취할 행동을 명시 Message Queue #include <sys/msg.h> int msgget(key_t key, int msgflg); • 새로운 msg Q를 생성하거나 기존 msg Q 에 접근 • 매개변수 • key : 고유의 msg Q에 접근하기 위해 사용(msg Q 구분) • shmflg : 접근 권한과, 생성 방식 정의 #include <sys/msg.h> int msgsnd(int msqid, condt void *msgp, size_t msgsz, int msgflg);

  21. msg Q를 해제하거나 권한을 변경 매개변수 shmctl의 매개변수와 비슷함 Message Queue #include <sys/msg.h> ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); • msg Q에 msg를 추출 • 매개변수 • msgq : Q에서 추출한 msg를 저장할 공간의 포인터 • msgtyp : 메시지의 선택을 위해 수신자에 의해 사용 #include <sys/msg.h> void msgctl(int msqid, int cmd, struct msqid_ds *buf);

  22. Quiz2 1/3 22 지금까지 배운 Message Queue 함수들을 사용해서 하나의 프로그램에서 입력 받은 문자열을 Message Queue에 전송하고 또 다른 프로그램에서 그 문자열을 수신하여 출력하는 프로그램을 작성하시오.

  23. Quiz2(msgq_send.c)2/3 23 헤더파일 <sys/types.h> <sys/ipc.h> <sys/msg.h> <stdio.h> <string.h> <stdlib.h> #define MSGMAX 256 typedef struct msgbuf { // Message structure. long mtype; char mtext[MSGMAX]; } message_buf; main() { int msqid; int msgflg = IPC_CREAT | 0666; key_t key; message_buf buf; size_t buf_length; char msg_str[MSGMAX]; // Create key. // Get the message queue id printf("\nmsgget: Calling msgget(%lx, %o)\n", key, msgflg); if (( message queue 에 접근 msgget() 사용) < 0) { perror("msgget"); exit(1); } else { printf("msgget: msgget succeeded: msqid = %d\n", msqid); } printf("Input your message : "); // fgets() 사용해서 문자열 입력받기 // Send message type is 1 buf.mtype = 1; // strcpy() 사용해서 buf.mtext 에 입력받은 문자열값 넣기 buf_length = strlen(buf.mtext) + 1 ; if(msgsnd() 사용해서 메시지 전송 마지막 인자는 IPC_NOWAIT < 0){ printf ("%d, %d, %s, %d\n", msqid, buf.mtype, buf.mtext, buf_length); perror("msgsnd"); exit(1); } else { printf("Sent message: %s\n", buf.mtext); } exit(0); }

  24. Quiz2(msgq_send.c)2/3 24 헤더파일 <sys/types.h> <sys/ipc.h> <sys/msg.h> <stdio.h> <string.h> <stdlib.h> #define MSGMAX 256 // message_buf 란 이름으로 Message structure 선언. main() { int msqid; key_t key; message_buf buf; // Create key. // Get the msg queue id if ((message queue 에 접근 msgget() 사용 < 0) { perror("msgget"); exit(1); } // Receive an answer of message type 1. if (msgrcv(msqid, &buf, MSGMAX, 1, 0) < 0) { perror("msgrcv"); exit(1); } printf("Receive message: %s\n", buf.mtext); exit(0); }

More Related