Linux System Programming

Slides:



Advertisements
Similar presentations
A 장형태.  병행프로세스 개요  상호배제 (Mutual Exclusion)  상호배제 ( 세마포어 )  모니터 (monitor)  프로세스간 2 가지 통신방법.
Advertisements

컴퓨터와 인터넷.
Linux System Programming
운영체제 Chapter 3 병형 프로세스 박요안.
운영체제 3주차 정리 박 남 규.
ㅎㅎ 구조체 구조체 사용하기 함수 매개변수로서의 구조체 구조체 포인터와 레퍼런스 구조체 배열.
2장. 프로그램의 기본 구성. 2장. 프로그램의 기본 구성 2-1"Hello, World!" 들여다 보기 /* Hello.c */ #include int main(void) { printf("Hello, World! \n"); return 0;
인공지능실험실 석사 2학기 이희재 TCP/IP Socket Programming… 제 11장 프로세스간 통신 인공지능실험실 석사 2학기 이희재
9장. C 언어의 핵심! 함수. 9장. C 언어의 핵심! 함수 9-1 함수의 정의와 선언 main 함수 다시 보기 : 함수의 기본 형태 { } 그림 9-1.
Java로 배우는 디자인패턴 입문 Chapter 5. Singleton 단 하나의 인스턴스
Task 통신 및 동기화 : Message Queue, Semaphore Shared Memory
Linux System Programming
제 9 장 구조체와 공용체.
Signal & Inter-Process Communication
공유 메모리[1] 공유 메모리 공유 메모리 생성: shmget(2) 같은 메모리 공간을 두 개 이상의 프로세스가 공유하는 것
Linux System Programming
조 병 규 Software Quality Lab. 한국교통대학교
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
Linux System Programming
제15장 파일 입출력 문자열을 출력하는 여러가지 방법 (15-2쪽) 문자열만 처리하는 입출력 함수
제 14장 Multicast & Broadcast
UNIT 07 Memory Map 로봇 SW 교육원 조용수.
10 시스템V의 프로세스간 통신.
10 시스템V의 프로세스간 통신.
양방향 파이프의 활용 양방향 통신 파이프는 기본적으로 단방향이므로 양방향 통신을 위해서는 파이프를 2개 생성한다.
12장 파이프.
Multi-thread Programming
07. 디바이스 드라이버의 초기화와 종료 김진홍
Multi-thread Programming
11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.
8장 함수 함수의 필요성 라이브러리 함수와 사용자 정의 함수 함수의 정의, 원형, 호출 배열을 함수 인자로 전달 재귀호출.
Multi-thread Programming
SqlParameter 클래스 선문 비트 18기 발표자 : 박성한.
컴퓨터 프로그래밍 기초 #02 : printf(), scanf()
4장 파일.
6장 파일 및 레코드 잠금.
메시지 큐[5] – test1.c 메시지 제어: msgctl(2) #include <sys/msg.h>
13장 고급 입출력 함수 박사 4학기 최 성자.
파일 접근권한 제어 stat 구조체의 st_mode 항목에 파일의 종류와 접근권한 정보저장 st_mode 값의 구조.
03. 병행 프로세스 (Parallel Process)
11장. 1차원 배열.
5 프로세스 정보.
사용자 함수 사용하기 함수 함수 정의 프로그램에서 특정한 기능을 수행하도록 만든 하나의 단위 작업
13장 프로세스 사이의 통신.
13. 포인터와 배열! 함께 이해하기 IT응용시스템공학과 김 형 진 교수.
UNIT 07 Memory Map 로봇 SW 교육원 조용수.
3장 상수 변수 기본 자료형 키워드와 식별자 상수와 변수 기본 자료형 형변환 자료형의 재정의.
병행 프로세스 이나현.
쉽게 풀어쓴 C언어 Express 제14장 포인터 활용 C Express Slide 1 (of 22)
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
자바 5.0 프로그래밍.
School of Electronics and Information. Kyung Hee University.
컴퓨터 프로그래밍 기초 - 10th : 포인터 및 구조체 -
Part 4 클래스 라이브러리 Chapter 10 : 다중 스레드 Chapter 11 : 패키지와 주요 클래스
Homework 7… 마지막 수업시간까지 (실습) 매개변수로 입력 받아 처리할 수 있도록 수정해 보세요
^^ Computer Programming 2 dmpr.cnu.ac.kr/~daygax.
병행프로세스의개요 주세호.
Multi-thread Programming
Homework #12 (1/2) 프로그램을 작성하고, 프로그램과 실행 결과를 프린트하여 제출한다.
병행 프로세스 병행처리는 프로세스들이 서로 관계없이 독립적으 로 수행 가능하고 다른 프로세스들과 협력을 필요로 하면서 기능 수행 3.1 개요 parbegin/parend 제어문 : 순차적인 수행으로부터 여러 개의 동시 수행으로 갈라짐을 지시하는 명령어와 여러 개의 동시.
3. 모듈 (5장. 모듈).
구조체(struct)와 공용체(union)
실습과제 1번 생성된 파일 basic.txt를 프로젝트 폴더에서 메모장으로 열고 내용을 확인
argc, argv 의 사용방법 #include <stdio.h>
06. 디바이스의 등록과 해제 김진홍
Signal & Inter-Process Communication
1장 C 언어의 개요 C 언어의 역사와 기원 C 언어의 특징 프로그램 과정 C 프로그램 구조 C 프로그램 예제.
13. 포인터와 배열! 함께 이해하기.
3장 파일 다루기 한빛미디어(주).
병행 프로세스(Parallel Process)
Presentation transcript:

Linux System Programming Lecture #10 – 세마포어(Semaphore)

세마포어(Semaphore) (1) 세마포어 정의 : 실행단위(프로세스 또는 쓰레드) 간의 동기화 도구 2개의 원자적 연산 P와 V가 정의되어 있는,정수값을 가지는 객체 s : 세마포어 P(s) : if ( s > 0 ) then s-- else   현재 프로세스는 대기한다; V(s) : if ( 1개 이상의 프로세스가 대기중 ) then   1개 프로세스만 진행한다 else   s++; 일상 생활에서의 ‘신호등’과 같은 동작을 수행 철도 교통을 통제하기 위한 깃발신호로부터 유래 Linux System Programming

세마포어(Semaphore) (2) 세마포어 정의 : 세마포어 연산 P & V 는 원자적 연산(atomic operation) 세마포어의 활용 상호 배제(mutual exclusion) 문제 – 두 개 이상의 프로세스가 하나의 공유 자원을 접근할 때에 한 순간에 하나의 프로세스만 공유 자원을 접근할 수 있도록 보장함 실행 동기화 – 두 개 이상의 프로세스간에 실행 순서에 맞추어 실행됨을 보장함 Linux System Programming

세마포어(Semaphore) (3) 세마포어 종류 : 이진 세마포어(Binary Semaphore) 0 또는 1의 정수 값만 가지는 세마포어 P(s) 연산은 세마포어 s가 1일 때에 0으로 변경 V(s) 연산은 세마포어 s가 0일 때에 1로 변경 하나의 자원에 대한 공유 및 동기화를 지원 계수형 세마포어(Counting Semaphore) 범위에 제한이 없는 정수 값을 가지는 세마포어 일반적으로 언급하는 세마포어 다수의 공유 자원에 대해 여러 프로세스가 접근할 때에 상호 배제 및 동기화를 지원 Linux System Programming

세마포어(Semaphore) (4) 세마포어 이용 : 공유 자원에 대한 상호 배제(Mutual Exclusion) 여러 개의 프로세스가 하나의 자원을 공유하는 경우, 동시에 여러 프로세스가 자원을 접근하면 예상하지 못하는 문제가 발생함 예: 동시에 여러 프로그램이 프린터에 출력을 시도하는 경우 해결책 – 상호 배제 한 순간에 하나의 프로세스만 공유 자원을 접근함을 보장함 임계 영역(Critical Section) : 전체 프로그램 중에서 공유자원을 접근하는 프로그램 영역 한 순간에 임계 영역을 실행하는 프로세스는 하나만 존재하도록 보장함 세마포어를 이용하여 상호 배제를 구현함 공유자원의 갯수에 따라 이진 세마포어 또는 계수형 세마포어를 사용 공유 자원에 대한 잠금과 풀기(lock & unlock) 기능을 지원 Linux System Programming

세마포어(Semaphore) (5) 세마포어 이용 : 공유 자원에 대한 상호 배제(Mutual Exclusion) (초기값: 1) P(s) P(s) Critical Section 공유 자원 Critical Section V(s) V(s) Linux System Programming

세마포어(Semaphore) (6) 세마포어 이용 : 프로세스간의 실행 동기화(Synchronization) 하나의 프로그램이 여러 개의 프로세스로 이루어지는 경우, 프로세스간의 종속성에 의해 실행 순서가 정해지며, 반드시 실행 순서에 의해 동작하여함 예: 하나의 프로세스가 다른 프로세스가 제공하는 데이터를 받아 동작하는 경우 해결책 – 프로세스 실행 동기화 프로세서 P1가 T1 문장을 실행한 후에 프로세스 P2가 T2 문장을 실행하여야 하는 경우 프로세스 P2는 T2 문자을 실행하기 전에 프로세스 P1이 T1 문장을 실행하여는지를 검사 프로세스 P1이 T1 문장을 실행하였으면 바로 T2 문장을 실행 프로세스 P1이 T2 문장을 실행하지 않았으면 실행할 때까지 대기 세마포어를 이용하여 동기화를 지원함 대개의 경우 이진 세마포어를 사용 Linux System Programming

세마포어(Semaphore) (7) 세마포어 이용 : 프로세스간의 실행 동기화(Synchronization) 프로세스 P1 (초기값: 0) V(s) P(s) Linux System Programming

세마포어(Semaphore) (8) 세마포어의 생성: semget 시스템 호출 Linux System Programming

세마포어(Semaphore) (9) 세마포어의 생성: semget 시스템 호출 세마포어 구조체: Linux System Programming

세마포어(Semaphore) (10) 세마포어의 생성: semget 시스템 호출 Semget 시스템 호출의 동작 세마포어 구조체 초기화: Linux System Programming

세마포어(Semaphore) (11) 세마포어의 제어: semctl 시스템 호출 세마포어 제어 연산 세마포어의 집합 안에 개별적인 세마포어나 모든 세마포어에 대해 세마포어 값을 읽어오거나 새로운 값을 설정 세마포어 집합의 상태 정보을 읽어오거나 변경 세마포어에서 대기중인 프로세스의 수를 결정 마지막으로 세마포어를 연산한 프로세스를 결정 세마포어를 제거 semctl 시스템 호출을 통해 상기의 세마포어 제어 연산을 실행 Linux System Programming

세마포어(Semaphore) (12) 세마포어의 제어: semctl 시스템 호출 Linux System Programming

세마포어(Semaphore) (13) 세마포어의 제어: semctl 시스템 호출 semctl 시스템 호출의 명령어 및 반환값 Linux System Programming

세마포어(Semaphore) (14) 세마포어의 제어: semctl 시스템 호출 세마포어 생성 세마포어 집합에서 하나의 세마포어를 초기화 세마포어 집합에서 하나의 세마포어 값 읽기 #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #define ANY 0 int semid, rtn; struct semid_ds semds; ushort us[5], init_us[5] = {0, 6, 7, 1, 4}; … semid = semget(key, 5, IPC_CREAT|0666); semctl(semid, 2, SETVAL, 7); // GETCNT, GETZCNT, GETPID도 같은 형태로 사용 semctl(semid, 2, GETVAL, ANY); Linux System Programming

세마포어(Semaphore) (15) 세마포어의 제어: semctl 시스템 호출 세마포어 집합 내의 모든 세마포어의 값을 초기화 세마포어 집합 내의 모든 세마포어의 값 읽기 세마포어의 소유자 변경 세마포어 집합 제거 semctl(semid, ANY, SETALL, init_us); semctl(semid, ANY, GETALL, us); // 접근 허가 모드 변경에도 같은 형태로 사용 semctl(semid, ANY, IPC_STAT, &semds); semds.sem_perm.uid = 51; semctl(semid, ANY, IPC_SET, &ds); semctl(semid, ANY, IPC_RMID, ANY); Linux System Programming

세마포어(Semaphore) (16) 세마포어의 제어: semop 시스템 호출 세마포어의 값을 증가시키거나 감소시키는 연산을 수행 Linux System Programming

세마포어(Semaphore) (17) 세마포어의 제어: semop 시스템 호출 Linux System Programming

세마포어(Semaphore) (18) 세마포어의 제어: semop 시스템 호출 Linux System Programming

예제 프로그램 (1) 예제 10-1 세마포어를 이용하여 공유 자원에 대한 접근을 제어하는 프로그램 공유 자원은 표준 출력 // file name : ex10-1.c // #include <sys/ipc.h> #include <sys/sem.h> #include <stdio.h> #define DUMMY 0 #define COUNT 4 int main(int argc, char *argv[]) { key_t ipckey; /* modified */ int semid, semget(),semctl(),semop(); int pid,getpid(); int creator,i; static struct sembuf lock = {0,-1,SEM_UNDO}; static struct sembuf unlock = {0, 1,SEM_UNDO}; setbuf(stdout,(char *) NULL); Linux System Programming

예제 프로그램 (2) ipckey = ftok(argv[0],'s'); if((semid = semget(ipckey,1,IPC_CREAT | IPC_EXCL | 0666)) != -1) { creator = 1; } else { if((semid = semget(ipckey,1,0)) == -1) { perror(argv[0]); exit(1); creator = 0; if(creator) { if(semctl(semid,0,SETVAL,1) == -1) { perror(argv[0]); exit(2); pid = getpid(); for(i=0;i<COUNT;i++){ if(semop(semid,&lock,1) == -1) { perror(argv[0]); exit(3); printf("\t[%d]locking\t",pid); sleep(1); printf("[%d] unlocking\n",pid); if(semop(semid,&unlock,1) == -1) { perror(argv[0]); exit(4); Linux System Programming

예제 프로그램 (3) if(creator) { sleep(5); if(semctl(semid,DUMMY,IPC_RMID,DUMMY) == -1) { perror(argv[0]); exit(5); } Linux System Programming

예제 프로그램 (4) 예제 10-2 다음 그림과 세 개의 세마포어를 갖는 세마포어 집합을 이용하여 프린터 자원을 관리하는 프로그램 첫번째 세마포어는 두 개의 프린터 모두를 관리하는 계수형 세마포어 두번째 및 세번째 세마포어는 각각 프린터1과 프린터2를 관리하는 세마포어 프린터는 단말기 장치를 PRINTER1으로, 정규 파일을 PRINTER2로 환경 변수를 정의하여 시뮬레이션한다 Linux System Programming

예제 프로그램 (5) #include <fcntl.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <stdio.h> #include "ex10-2.h" #define DUMMY 0 #define NUMPR 2 #define ACQUIRE -1 #define RELEASE 1 int main(int argc,char *argv[]) { char *getenv(), *printer[NUMPR], buf[BUFSIZ]; key_t ipckey; /* modified */ int semid, semget(), semctl(), semop(); ushort initial[NUMPR +1]; int i, prntnum, creator, getpid(); int n, fdin, fdout; struct sembuf operation[2]; char errmsg[30]; if((printer[1] = getenv("PRINTER1")) == (char *) NULL || (printer[2] = getenv("PRINTER2")) == (char *) NULL) { printf("missing printer assignment\n"); exit(1); } Linux System Programming

예제 프로그램 (6) if(strncmp(argv[0],"line",4) ==0) prntnum = 1; else if(strncmp(argv[0],"lase",4) ==0) prntnum =2; else prntnum = getpid() % NUMPR +1; ipckey = ftok(argv[0], 's'); if((semid = semget(ipckey,NUMPR +1,IPC_CREAT| IPC_EXCL| 0666)) != -1) { creator = 1; } else { if((semid = semget(ipckey, NUMPR +1, 0666)) == -1) { sprintf(errmsg, "%s - semget", argv[0]); perror(errmsg); exit(2); } if(creator) { /* initialize semaphore set */ initial[0] = NUMPR; for(i=1; i<= NUMPR; i++) initial[i] = 1; if(semctl(semid, DUMMY, SETALL, initial) == -1) { sprintf(errmsg,"%s -SETALL", argv[0]); perror(errmsg); exit(3); operation[1].sem_num = prntnum; operation[1].sem_op = ACQUIRE; operation[1].sem_flg = SEM_UNDO; operation[0].sem_num = 0; operation[0].sem_op = ACQUIRE; operation[0].sem_flg = SEM_UNDO; Linux System Programming

예제 프로그램 (7) if(semop(semid, operation, 2) == -1) { sprintf(errmsg,"%s - ACQUIRE", argv[0]); perror(errmsg); exit(4); } if((fdin = open(argv[1], O_RDONLY)) == -1) { sprintf(errmsg,"%s - %s", argv[0], argv[1]); perror(errmsg); exit(5); if((fdout = open(printer[prntnum], O_CREAT| O_WRONLY)) == -1) { sprintf(errmsg,"%s - %s", argv[0], printer[prntnum]); perror(errmsg); exit(6); while((n= read(fdin, buf, BUFSIZ)) > 0) write(fdout, buf, n); operation[1].sem_op = RELEASE; operation[0].sem_op = RELEASE; sprintf(errmsg,"%s - RELEASE", argv[0]); perror(errmsg); exit(7); Linux System Programming

예제 프로그램 (8) 예제 10-3 다음 그림과 같은 생산 라인을 시뮬레이션하는 프로그램 각 공정은 다중 프로세스를 생성하고 이들의 생산 순서와 소비 시간을 세마포어와 프로세스 수면(sleep)을 이용하여 시뮬레이션한다 Linux System Programming

예제 프로그램 (9) // // header file name : ex10-3.h #define NWIDGETS 5 #define PARTA 0 #define PARTB 1 #define PARTC 2 #define SUB1 3 #define HOLDER 0 Linux System Programming

예제 프로그램 (10) // // source file name : ex10-3a.c #include <signal.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include "ex10-3.h" int semprodn; void endsim(); int main(int argc, char *argv[]) { int widget; int pgrp; char asc_prod_key[20]; static struct sembuf partc_sub1[2] = { { PARTC, -1, SEM_UNDO}, { SUB1, -1, SEM_UNDO} }; if((semprodn=semget(IPC_PRIVATE,4,IPC_CREAT | 0640)) == -1) printf("Can't get production line semaphore set\n"); exit(1); } Linux System Programming

예제 프로그램 (11) signal(SIGINT, endsim); sprintf(asc_prod_key,"%d", semprodn); if( fork() == 0) execl("ex10-3b","a", asc_prod_key, (char *)0); if( fork() == 0) execl("ex10-3b","b", asc_prod_key, (char *)0); if( fork() == 0) execl("ex10-3b","c", asc_prod_key, (char *)0); if( fork() == 0) execl("ex10-3c","ex10-3c", asc_prod_key, (char *)0); for(widget=1; widget < NWIDGETS; widget++) { semop(semprodn, partc_sub1, 2); printf("%s: ready to make widget #%d\n", argv[0], widget); } endsim(); void endsim() { semctl(semprodn, 0,IPC_RMID, 0); signal(SIGTERM, SIG_IGN); kill(0, SIGTERM); exit(); Linux System Programming

예제 프로그램 (12) // // source file name : ex10-3b.c #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include "ex10-3.h" int main(int argc, char *argv[]) { int semprodn, index; int unit = 0; static struct sembuf parti = { HOLDER, 1, SEM_UNDO }; static int prodtimeabc[3] = {2,3,4}; semprodn = atoi( argv[1] ); index = argv[0][0]- 'a'; /* argv[0] == [abc] */ parti.sem_num = index; while(1) { semop(semprodn, &parti, 1); printf("%s: producing unit #%d\n", argv[0], ++unit); sleep(prodtimeabc[index]); } Linux System Programming

예제 프로그램 (13) // // source file name : ex10-3c.c #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include "ex10-3.h" int main(int argc, char *argv[]) { int semprodn; int unit = 0; static struct sembuf part_ab[2] = { {PARTA, -1, SEM_UNDO }, {PARTB, -1, SEM_UNDO } }; static struct sembuf sub1 = { SUB1, 1, SEM_UNDO }; semprodn = atoi( argv[1] ); while(1) { semop(semprodn, part_ab, 2); semop(semprodn, &sub1, 1); printf("%s: producing sub-assembly #%d\n", argv[0], ++unit); } Linux System Programming