Linux System Programming

Slides:



Advertisements
Similar presentations
Linux System Programming
Advertisements

Linux/UNIX Programming APUE (The Environment of a UNIX Process)
2016 ITA 1월 강의 C Programming -4일차- 포인터배열 및 이중포인터 정대진 ( )
Understanding of Socket and File I/O
6 레이스 컨디션.
13장 소켓.
Task 통신 및 동기화 : Message Queue, Semaphore Shared Memory
제 8 장  파서 생성기 YACC 사용하기.
Linux System Programming
Department of Computer Engineering
인공지능실험실 석사 2학기 김승겸 TCP/IP Socket Programming… 제 10장 멀티태스킹 기반의 서버구현 인공지능실험실 석사 2학기 김승겸
Signal & Inter-Process Communication
공유 메모리[1] 공유 메모리 공유 메모리 생성: shmget(2) 같은 메모리 공간을 두 개 이상의 프로세스가 공유하는 것
디바이스 드라이버 기초 디바이스 드라이버의 개요 파일 연산 디바이스 드라이버 등록 디바이스 드라이버 구성
디바이스 드라이버 개요 가상 디바이스드라이버 실습
Department of Computer Engineering
쉽게 풀어쓴 C언어 Express 제17장 동적 메모리와 연결 리스트 C Express.
Multi-thread Programming
Network Lab. Seoung Hyeon, Lee
6 프로세스 생성과 실행.
6장 비연결형 지향 프로토콜 Database Lab 강 우 석.
14장 소켓.
Chapter 13 문자 데이터와 문자열 문자 데이터 문자열.
제 12장 I/O멀티플렉싱(Multiplexing)
FND (Flexible Numeric Display)
10장 메모리 관리.
쉽게 풀어쓴 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
10 시스템V의 프로세스간 통신.
12장 파이프.
fork로 생성한 자식 프로세스에서 exec 함수군을 호출
Linux System Programming
멀티쓰레드 기반의 서버구현 School of Electronics and Information.
Department of Computer Engineering
쉽게 풀어쓴 C언어 Express 제14장 포인터 활용 C Express.
Term Project Team Member
Homework 6… 12월 2일(금) 11:59pm까지 자신의 이름과 학번을 출력해 주는 유닉스/리눅스 네트워크 소켓 서버 프로그램 과 클라이언트 프로그램 을 작성해 보세요 참고 (실습1) Hello 프로그램 helloserver.c helloclient.c 컴파일.
Linux/UNIX Programming APUE (Interprocess Communication)
Advanced Socket Programming
6장 파일 및 레코드 잠금.
메시지 큐[5] – test1.c 메시지 제어: msgctl(2) #include <sys/msg.h>
Department of Computer Engineering
10장 C 표준 파일 입출력 子曰 學而時習(실습?)之 不亦悅乎.
5 프로세스 정보.
18강 파일처리함수(2) 강 의 내 용 순차파일 만들기와 읽기 순차파일 입출력함수 랜덤파일 처리
제 11 장 전처리기.
adopted from KNK C Programming : A Modern Approach
문자 디바이스 드라이버 임베디드 시스템.
Signal & Inter-Process Communication
Memory & Data Management.
컴퓨터의 기초 제 2강 - 변수와 자료형 , 연산자 2006년 3월 27일.
Analog to Digital Converter
네트워크 프로그래밍의 이해 School of Electronics and Information.
Operating System 10주차 - IPC(InterProcess Communication) -
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
Stepper Motor 디바이스 드라이버
조 병 규 Software Quality Lab. 한국교통대학교
Fflush 사용이유 및 방법 [이유] 키보드에서 입력된 내용은 입력버퍼에 저장되었다가 Enter 키가 들어오면 프로그램으로 전달됨 이 때 입력버퍼에 있는 Enter 키도 프로그램으로 전달됨 그러므로 아래와 같은 프로그램에서 문자 하나를 입력해도 Enter키도 입력된 것으로.
Department of Computer Engineering
실습과제 1번 생성된 파일 basic.txt를 프로젝트 폴더에서 메모장으로 열고 내용을 확인
argc, argv 의 사용방법 #include <stdio.h>
Signal & Inter-Process Communication
C 13장. 입출력 라이브러리 #include <stdio.h> int main(void) { int num;
C.
3장 파일 다루기 한빛미디어(주).
Presentation transcript:

Linux System Programming Lecture #9 – 메시지 큐(Message Queue)

동일한 플랫폼 상에서 유사하게 구현되어 ICP 도구로 별도 분류하기도 함 IPC(Inter-Process Communication) (1) 프로세스 통신 도구(IPC Facilites) : 비동기적으로 동작하는 프로세스간의 통신을 위하여 운영체제가 제공하는 도구 종류: Signal(신호) Pipe(파이프) Message Queue(메시지 큐) Semaphore(세마포어) Shared Memory(공유 메모리) Socket(소켓) 동일한 플랫폼 상에서 유사하게 구현되어 ICP 도구로 별도 분류하기도 함 Linux System Programming

IPC(Inter-Process Communication) (2) 프로세스 통신 도구 (IPC Facilites) : 세마포어(Semaphore) 프로세스 동기화와 자원 관리에 사용 프로세스간의 상호배제 문제 해결에 사용 공유 메모리(Shared Memory) 가장 빠른 프로세스 통신 도구 하나 이상의 프로세스에 부착하여 서로 공유하여 접근 가능 프로세스간의 공유 메모리 접근을 위해 동기화가 필요 메시지 큐(Message Queue) 프로세스들간에 이산적인 양의 데이터 송수신을 위해 사용 전송할 데이터를 메시지 형태로 생성하여 전달하고 메시지 수신을 통해 데이터 수신이 가능 인터넷 메일 서비스와 개념이 유사 Linux System Programming

IPC(Inter-Process Communication) (3) get ctl op 세마포어 semget semctl semop 공유 메모리 shmget shmctl shmop(shmat, shmdt) 메시지큐 msgget msgctl msgop(msgsnd, msgrcv) 기 능 IPC 도구의 생성 및 참조 기능 제공 소유자 및 접근 허가 변경 등의 기능 제공 IPC 도구의 연산(송수신 제어 등) 기능 제공 Linux System Programming

IPC(Inter-Process Communication) (4) get 시스템 호출 파일 열기 시스템 호출 open과 유사 새롭게 통신 도구를 생성하거나 이미 생성된 통신 도구에 대한 id를 반환하여 접근 가능하게 함 반환된 id는 파일 디스크립터와 비슷하게 동작 접근 허가 또한 파일 접근 허가와 비슷하게 규정 ctl 시스템 호출 통신 도구에 관한 상태 정보 읽기 몇몇 상태 정보(소유자, 그룹, 접근 허가 등)에 대한 변경 통신 도구의 제거 기능 op 시스템 호출 프로세스간의 데이터 전송을 실행 파일 시스템 호출 read/write와 유사 Shmat는 파일의 open과 유사하고, shmdt는 파일의 close와 유사 Linux System Programming

IPC(Inter-Process Communication) (5) IPC 도구 식별자 – IPC key 파일을 식별하기 위해 파일 이름을 사용하듯이 IPC 객체를 식별하기 위해 사용하는 정수형 숫자 프로세스들은 IPC key를 이용하여 IPC 자원을 공유 자료형: key_t (<sys/types.h>에 정의) IPC key 변환 시스템 호출 – ftok(file_to_key) IPC 도구의 공유를 편리하게 지원하기 위해 파일 경로명과 식별자를 IPC 도구에 부여하고, 이를 IPC key 값으로 변환하는 시스템 호출 char device Inode # of file key_t Linux System Programming

IPC(Inter-Process Communication) (6) IPC key 변환 시스템 호출 – ftok(file_to_key) Linux System Programming

IPC(Inter-Process Communication) (7) IPC 도구의 접근 허가 구조: struct ipc_perm 파일의 접근 허가와 유사한 기능을 지원 접근 모드에서 실행 모드는 무의미함 Linux System Programming

IPC(Inter-Process Communication) (8) IPC 도구 유형별로 생성된 IPC 객체를 관리하기 위해 운영체제가 유지하는 테이블 IPC 도구 유형별로 각각의 테이블을 유지 파일 테이블과 유사한 개념 Linux System Programming

IPC(Inter-Process Communication) (9) ipcs 명령 현재 사용중인 IPC 도구들의 상태(status)를 보여주는 명령 IPC 타입, 사용자 ID, key 값 그리고 접근 허가 등을 볼 수 있음 옵션을 사용하여 지정된 유형의 IPC 도구 상태 정보만을 접근 가능 -q : 메시지 큐, -m : 공유 메모리, -s : 세마포어 ipcrm 명령 IPC 객체를 제거하는 명령 IPC 도구 유형 및 key 값을 지정하는 원하는 IPC 객체를 제거 Linux System Programming

메시지 큐(Message Queue) (1) 메시지 큐: 프로세스간에 이산적인 데이터를 메시지 형태로 전송하는 통신 도구 파이프와 같이 FIFO 타입의 데이터 전송을 지원 메시지는 메시지와 바이트(byte)들의 모임으로 구성 메시지 유형은 정수값으로 여러가지 메시지 형태에 id를 부여하여 구별하기 위해 사용 바이트 모임은 전송하는 데이터를 의미하는 것으로 문자, 그림 또는 일련의 구조체 데이터 등을 전송하기 위햇 사용 관련 시스템 호출 함수 msgget() – 메시지 큐를 생성 msgsnd()/msgrcv() – 메시지 전송 및 수신 msgctl() – 메시지 큐 제어 Linux System Programming

메시지 큐(Message Queue) (2) 메시지 큐의 구조: 메시지 큐의 상태 구조체 : msgid_ds 메시지 큐 객체의 상태 정보를 저장하는 구조체 하나의 메시지 큐가 생성되면 하나의 msgid_ds 구조체가 생성 Linux System Programming

메시지 큐(Message Queue) (3) 메시지 큐의 동작: 전송 프로세스가 전송할 데이터를 메시지 형태로 만들어 메시지를 전송하면 전송된 메시지는 메시지 큐의 마지막에 연결된다 수신 프로세스는 메시지 큐에 존재하는 메시지를 선택적으로 수신할 수 있다. 수신 프로세스에서는 메시지를 수신할 때에 다음의 수신 정책 중에 하나를 지정하여야 한다. 메시지 큐에서 첫번째 메시지 메시지 큐에서 지정된 타입의 첫번째 메시지 메시지 큐에 있는 타입들의 범위들로 부터 첫번째 메시지 Linux System Programming

메시지 큐(Message Queue) (4) 메시지 큐의 생성: msgget msgget – 메시지 큐 생성 시스템 호출 주어진 key를 갖는 메시지 큐가 존재하면 메시지 큐의 id를 반환하고, 그렇지 않으면 새롭게 메시지 큐를 생성하고 id를 반환 Linux System Programming

메시지 큐(Message Queue) (5) 메시지 큐의 생성: msgget 메시지 큐 구조체: msqid_ds Linux System Programming

메시지 큐(Message Queue) (6) 메시지 큐의 생성: msgget 메시지 큐 구조체의 초기값 Linux System Programming

메시지 큐(Message Queue) (7) 메시지 큐의 생성: msgget msgget 시스템 호출의 flag 옵션 Linux System Programming

메시지 큐(Message Queue) (8) 메시지 큐의 제어: msgctl msgctl - 메시지 큐 제어 시스템 호출 메시지 큐의 상태를 질의하거나 상태 정보를 변경, 또는 메시지 큐를 제거하는 기능을 지원 Linux System Programming

메시지 큐(Message Queue) (9) 메시지 큐의 제어: msgctl msgctl 시스템 호출의 명령어 Linux System Programming

메시지 큐(Message Queue) (10) msgctl 시스템 호출의 사용 예 메시지 큐 관련 자료 구조 선언 메시지 큐의 제거 메시지 큐의 소유자 변경 #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> int msqid; struct msqid_ds ds; msgctl(msqid, IPC_RMID, (struct msqid_ds *)0); msgctl(msqid, IPC_STAT, &ds); ds.msg_perm.uid = 51; msgctl(msqid, IPC_SET, &ds); Linux System Programming

메시지 큐(Message Queue) (11) msgctl 시스템 호출의 사용 예 메시지 큐의 접근 허가 변경 메시지 큐의 메시지 크기 변경 msgctl(msqid, IPC_STAT, &ds); ds.msg_perm.mode = 0660; msgctl(msqid, IPC_SET, &ds); msgctl(msqid, IPC_STAT, &ds); ds.msg_qbytes = 5000; msgctl(msqid, IPC_SET, &ds); Linux System Programming

메시지 큐(Message Queue) (12) 메시지 큐의 연산: msgsnd, msgrcv 메시지 구조체 : 메시지 유형은 전송되는 여러가지 유형의 메시지 형태를 분류하여 지정 메시지 텍스트는 전송하는 데이터를 저장 메시지 텍스트의 크기는 최소 0에서 최대 64 KB 이내이며, 묵시적으로 2048 바이트로 사용 #include <sys/msg.h> struct msgbuf { long mtype; /* 메시지 유형 */ char mtext[1]; /* 메지시 텍스트 */ } Linux System Programming

메시지 큐(Message Queue) (13) 메시지 큐의 연산: msgsnd, msgrcv 메시지 송신 시스템 호출 : msgsnd Linux System Programming

메시지 큐(Message Queue) (13) 메시지 큐의 연산: msgsnd, msgrcv msgsnd 시스템 호출에 의한 메시지 큐 구조체 변경 Linux System Programming

메시지 큐(Message Queue) (14) 메시지 큐의 연산: msgsnd, msgrcv 메시지 수신 시스템 호출 : msgrcv Linux System Programming

메시지 큐(Message Queue) (15) 메시지 큐의 연산: msgsnd, msgrcv msgrcv 시스템 호출에서의 메시지 타입 지정 msgrcv 시스템 호출에 의한 메시지 큐 구조체 변경 Linux System Programming

예제 프로그램 (1) 예제 9-1 하나의 메시지를 전송하고 수신하는 프로그램을 작성하여라 // file name : ex9-1a.c // #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> struct { long t; char a[60]; } x = {11L,"hello"}; main() { int mid; mid = msgget(11L,IPC_CREAT| 0666); msgsnd(mid,&x,strlen(x.a)+1,0); sleep(60); msgctl(mid,IPC_RMID,0); } Linux System Programming

예제 프로그램 (2) // file name : ex9-1b.c // #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> struct { long t; char a[60]; } x ; main() { int mid,rtn; mid = msgget(11L,0); rtn=msgrcv(mid,&x,60,0L,0); printf("rtn=%d type=%d text=%s\n",rtn,x.t,x.a); } Linux System Programming

예제 프로그램 (3) 예제 9-2 예제 9-1을 개선하여 여러 개의 메시지를 송수신하는 프로그램을 작성하여라. // file name : ex9-2a.c // #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #define MAX_SEND_SZ 30 #define DONE 99L main() { void perror(); key_t key; int mid; static struct { long mtype; char mtext[MAX_SEND_SZ]; } buf; Linux System Programming

예제 프로그램 (4) static char *string[3] = { "hello", "how are you", "good-bye"}; int i,rtn; if((key= ftok(".",'a'))==-1) { perror("Can\'t form key"); exit(1); } mid = msgget(key,IPC_CREAT| 0660); if(mid == -1) { perror("Sender can not make msg queue!"); exit(2); Linux System Programming

예제 프로그램 (5) buf.mtype = 1L; for(i=0;i<3;i++) { strcpy(buf.mtext,string[i]); if(msgsnd(mid,&buf,strlen(buf.mtext)+1,0)==-1) { perror("Sender can not msgsnd!"); exit(3); } rtn = msgrcv(mid,&buf,MAX_SEND_SZ,DONE,0); if(rtn == -1) { perror("Sender can not msgrcv"); exit(4); msgctl(mid,IPC_RMID,0); Linux System Programming

예제 프로그램 (6) // file name : ex9-2b.c // #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #define MAX_RECV_SZ 60 #define FIFO 0L #define ZERO_LEN 0 #define DONE 99L static struct { long mtype; char mtext[MAX_RECV_SZ]; } buf; key_t key; int mid; int rtn; Linux System Programming

예제 프로그램 (7) main(int argv,char *argc[]) { void perror(); if((key= ftok(".",'a'))==-1) { perror("Can\'t form key"); exit(1); } mid = msgget(key,0); if(mid == -1) { perror("Receiver can not access msg queue!"); exit(2); while(1) { rtn = msgrcv(mid,&buf,MAX_RECV_SZ,FIFO,0); printf("rtn=%d buf.mtype=%ld buf.mtext=%s\n", rtn,buf.mtype,buf.mtext); if(!strcmp(buf.mtext,"good-bye")) break; buf.mtype = DONE; msgsnd(mid,&buf,ZERO_LEN,0); Linux System Programming

예제 프로그램 (8) 예제 9-3 메시지 송신 프로그램가 키보드 입력을 메시지로 만들어 여러 개의 수신 프로그램에 전달하는 프로그램을 작성하여라. 송신 프로그램은 fork()/exec() 시스템 호출을 통하여 수신 프로세스를 생성하고, 수신 프로세스는 수신된 메시지를 표준 출력으로 출력하도록 한다. // file name : ex9-3a.c // #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #define MAX_SZ 80 #define NCHILD 3 Linux System Programming

예제 프로그램 (9) #define WAIT_SOLE_USE(MSGQID) { \ int still_active = NCHILD; \ int i; \ long s_pid; \ s_pid = getpid(); \ while(still_active) { for(i=0;i<NCHILD;i++) \ if(msgrcv(MSGQID,&buf,MAX_SZ,s_pid,IPC_NOWAIT) != -1) \ if(!strncmp(buf.mtext,"DONE",4)) still_active--; \ sleep(2); \ } \ } main() { void perror(); key_t ftok(); int msgqid; struct { long mtype; char mtext[MAX_SZ]; } buf; Linux System Programming

예제 프로그램 (10) int msg_length; static char qid_evar[40]; static char *envp[2] = { qid_evar }; int this_fork, child; long r_pid[NCHILD]; char child_name[20]; int eof = 0; if((msgqid = msgget(IPC_PRIVATE,IPC_CREAT | 0660)) == -1) { perror("Sender can't make message queue!"); exit(1); } sprintf(qid_evar,"MQID=%d",msgqid); for(child=0;child<NCHILD;child++) { this_fork = fork(); if(this_fork == -1) { perror("fork failed"); exit(2); else if(this_fork == 0) { sprintf(child_name,"mwall_r%d",child); execle("ex9-3b",child_name,0,envp); perror("exec failed"); exit(3); else r_pid[child] = (long) this_fork; Linux System Programming

예제 프로그램 (11) setbuf(stdout,(char *) 0); while(1) { fprintf(stdout, "Enter message to be sent to all receivers:"); if(gets(buf.mtext) == (char *) 0) { fprintf(stdout,"\n"); eof++; strcpy(buf.mtext,"EOF"); } msg_length = strlen(buf.mtext) +1; for(child=0;child<NCHILD;child++) { buf.mtype = r_pid[child]; if(msgsnd(msgqid,&buf,msg_length,0) == -1) { perror("Producer msgsnd error"); exit(4); if(eof) break; sleep(1); WAIT_SOLE_USE(msgqid); msgctl(msgqid,IPC_RMID,0); Linux System Programming

예제 프로그램 (12) // file name : ex9-3a.c // #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #define MAX_SZ 80 main(int argc, char *argv[]) { void perror(); char *getenv(); long pid; char *valuep; int msgqid; struct { long mtype; char mtext[MAX_SZ]; } buf; Linux System Programming

예제 프로그램 (13) pid = (long) getpid(); if((valuep = getenv("MQID")) == NULL) { fprintf(stderr,"%s:can't get env MQID\n",argv[0]); exit(1); } else sscanf(valuep,"%d",&msgqid); while(1) { msgrcv(msgqid,&buf,MAX_SZ,pid,MSG_NOERROR); printf("%s received '%s'\n",argv[0],buf.mtext); if(!strcmp(buf.mtext,"EOF")) break; buf.mtype = (long) getppid(); strcpy(buf.mtext,"DONE"); if(msgsnd(msgqid,&buf,strlen(buf.mtext),0) == -1) { fprintf(stderr,"%s:msgsnd error\n",argv[0]); exit(2); exit(0); Linux System Programming