linux programming study

63
Linux programming [IGRUS] -pineoc 이이이

Upload: yun-seok-lee

Post on 12-Apr-2017

650 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Linux programming study

Linux programming[IGRUS] -pineoc 이윤석

Page 2: Linux programming study

주요 챕터 각각의 챕터에 대한 이론 코드 및 설명 공부하면서 배운 것 , 느낀점 .

목차

Page 3: Linux programming study

Ch3. 파일 다루기 Ch11. 프로세스와 신호 Ch12. 쓰레드 Ch13. 프로세스간 통신 : 파이프 Ch14. 세마포 , 공유 메모리 , 메시지 큐 Ch15. 소켓

주요 챕터

Page 4: Linux programming study

파일과 디렉토리를 다루는 여러 가지 함수들을 상세히 설명하는 데 주력 .◦ 파일과 장치◦ 시스템 호출◦ 라이브러리 함수◦ 파일 다루기◦ 표준 I/O 라이브러리◦ 입 , 출력 서식화◦ 파일과 디렉터리 관리◦ 디렉터리 탐색◦ 오류처리 , /proc 파일 시스템 , fcntl 과 mmap

Ch3. 파일다루기

Page 5: Linux programming study

저수준 파일 접근하나의 프로그램이 시동될 때에는 일반적으로 세 개의 파일 서술자들이 이미 열린 상태이다 .

- 0 : 표준 입력- 1 : 표준 출력- 2 : 표준 오류위의 파일 서술자는 자동으로 열리며 , 따라서 프로그램은 별다른 절차 없이Write 를 이용 , 즉시 해당 장치에 자료를 기록할 수 있다 .

Ch3. 파일다루기

Page 6: Linux programming study

WriteWrite 시스템 호출은 버퍼 buf 에 있는 처음 nbytes 개의 바이트들을 파일 서술자 fildes 에 연관된 파일에 기록하고 , 실제로 기록한 바이트 수를 돌려준다 .

시스템 호출의 구문#include <unistd.h>Size_t write(int fildes, const void* buf, size_t nbytes);

Ch3. 파일다루기

Page 7: Linux programming study

ReadRead 시스템 호출은 파일 서술자 fildes 에 연관된 파일로부터 nbytes 개의 바이트들을 읽어서 그 바이트들을 버퍼 buf 에 집어넣는다 .반환값은 실제로 읽은 바이트 개수인데 , 요청한 바이트 수보다 작을 수도 있다 .반환값이 0 이면 아무 것도 읽지 않은 것이다 ( 파일의 끝에 도달한 경우 ). -1 은 오류를 의미#include <unistd.h>Size_t read(int fildes, void *buf,size_t nbytes);

Ch3. 파일다루기

Page 8: Linux programming study

Open새 파일 서술자를 만들기 위해서는 open 시스템 호출을 사용해야 한다 .#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>Int open(const char* path, int oflags);Int open(const char* path, int oflags, mode_t mode);

간단히 말하자면 open 은 파일 또는 장치로의 접근 경로를 만듬 . Flag 값을 통해 모드 설정 , O_RDONLY, O_WRONLY, O_RDWR 각각 읽기 , 쓰기 , 읽기 쓰기 가능하게 하는 모드 .( 이들 중 하나를 반드시 지정해야 한다 .)( 다른 플래그 값이 있지만 상세한 부분은 생략한다 .)

Ch3. 파일다루기

Page 9: Linux programming study

초기 권한그림에서 보듯이 , drwxrwxr-x : 디렉토리 , 사용자 , 그룹 , 다른 사용자R 은 읽기권한 , w 는 쓰기 , x 는 실행 이다 .

이 후에 close 함수 , ioctl 함수가 있는데 close 는 파일 서술자와 파일의 연관을 끊는 함수 , ioctl 함수는 파일 서술자 (fildes) 가 가리키는 대상에 대해 cmd 로 지정된 기능을 수행한다 .

Ch3. 파일다루기

Page 10: Linux programming study

나머지 파일 관리 관련 시스템 호출들-lseek : 파일 서술자 (fildes) 가 가리키는 파일의 읽기 / 쓰기 포인터 설정한다 .-fstat,stat,lstat : 파일서술자에 연관된 파일의 상태 정보를 돌려준다 .-dup, dup2 : 파일 서술자를 복제하는 데 쓰인다 .

이 호출들에 대한 변수나 자세한 사항은 참조하여 사용한다 .

Ch3. 파일다루기

Page 11: Linux programming study

표준 I/O 라이브러리-> 표준 I/O 라이브러리와 해당 헤더 파일은 저수준 I/O 시스템 호출들에 대한 융통성 있는 인터페이스를 제공한다 . 아래에 설명할 부분은 저수준 시스템 호출이다 .-fopen : 이 함수는 주로 파일과 터미널의 입 . 출력에 쓰인다 . 장치들을 좀 더 명시적으로 제어하려면 저수준 시스템 호출을 사용하는 것이 좋다 .-fread : 파일 스트림으로부터 자료를 읽는데 쓰인다 . 읽은 자료는 ptr 이 가리키는 자료 버퍼에 기록된다 .fread, fwrite 모두 자료를 레코드 단위로 처리한다 .-fclose : 스트림 매개변수로 지정된 스트림을 닫는다 . 이때 아직 기록되지 않은 자료가 모두 기록된다 . 명시적으로 사용해주면 좋다 .-fwrite : 인터페이스는 fread 와 비슷하다 . 출력 스트림에 기록 , 성공적으로 기록한 레코드 개수를 돌려준다 .-fflush : 주어진 파일 스트림에 대해 대기 중인 모든 자료를 즉시 기록한다 .예 ) 대화식 프롬프트가 확실히 터미널에 출력된 후에만 사용자의 입력을 받아 들여야하는 경우에 유용 .fclose 호출하는 시점에서는 fflush 를 굳이 호출할 필요가 없다 . * 헤더파일은 stdio.h 이다 .

Ch3. 파일다루기

Page 12: Linux programming study

표준 I/O 라이브러리-fseek : 시스템 호출 lseek 에 해당 . 이 함수는 스트림에서 다음번에 자료를 읽거나 쓸 위치를 설정한다 . 차이점은 lseek 은 off_t, fseek 은 성공시 0, 실패시 -1 반환한다 .-fget, getc, getchar : 파일 스트림에서 다음 바이트 ( 문자 ) 를 돌려준다 . 파일의 끝에 도달했거나 오류가 있다면 EOF 를 돌려준다 .-fputc, putc, putchar : fputc 는 문자 하나를 출력 스트림에 기록한다 . 성공 시 문자의 값을 돌려주고 , 실패 시 EOF 를 돌려준다 .-fgets, gets : 입력 파일 스트림에서 하나의 문자열을 읽어 들인다 . Ex) char* fgets(char* s, int n, FILE* stream);

char* gets(char* s);->s 가 가리키는 문자열에 넣되 새 줄 문자를 만나거나 , n-1 개의 문자들을 읽었거나 , 파일의 끝에 도달하면 멈춘다 . 새 줄 문자도 s 에 저장된다 .

*EOF 는 End Of File 의 약자

Ch3. 파일다루기

Page 13: Linux programming study

서식화된 입력과 출력-printf, fprintf, sprintf : 서로 다른 형식의 여러 인수들을 서식화해서 출력한다 .-scanf, fscanf, sscanf : 스트림으로부터 값들을 읽고 그것들을 포인터 매개변수들이 가리키는 변수들에 집어넣는다 . - 기타 다른 함수들도 많지만 ( 표준 스트림 stdin, stdout,stderr 을 사용하는 함수들 )파일 스트림에 대한 설정이나 위치설정 등이다 .

Ch3. 파일다루기

Page 14: Linux programming study

파일과 디렉터리의 생성 및 관리- 파일 , 디렉터리의 생성 및 관리를 위한 여러 표준 라이브러리 함수들과 시스템 호출 .-chmod : 시스템 호출로 , 파일이나 디렉터리의 접근 권한을 변경하는 데 쓰인다 .-chown : 슈퍼사용자는 이 시스템 호출로 파일의 소유자를 변경할 수 있다 .-unlink : 파일의 제거 .-mkdir, rmdir : 디렉토리의 생성 , 제거 . 권한 설정은 umask 에 의존한다 .-chdir 와 getcwd : 현재 디렉토리 변경 시 chdir 시스템 호출 . 현재 디렉토리를 알고 싶을 때는 getcwd 함수 사용 .-opendir : 디렉터리를 열고 그에 대한 디렉터리 스트림을 만듬 . 성공시 디렉터리 항목들을 읽는데 사용할 DIR 구조체를 가리키는 포인터를 돌려준다 .-readdir : 디렉터리 스트림 안의 다음 디렉터리 항목에 대한 구조체의 포인터를 반환 .-telldir : 디렉터리의 스트림의 현재 위치에 해당하는 값을 돌려준다 .-seekdir : 주어진 디렉터리 스트림의 현재 디렉터리 항목 위치를 변경한다 .-closedir : 디렉터리 스트림을 닫고 그에 연관된 자원들을 해제한다 . 성공 시 0 반환 .

Ch3. 파일다루기

Page 15: Linux programming study

오류처리-strerror : 주어진 오류 번호에 해당하는 오류 메시지 문자열을 반환한다 .-perror : 오류 번호를 직접 받는 대신 현재 errno 에 설정된 값을 사용 .

/PROC 파일 시스템-> 이 파일 시스템이 제공하는 것은 드라이버들과 커널 기능 .

Fcntl 과 mmap->fcntl 은 저수준 파일 서술자를 통해 파일을 좀 더 세밀하게 제어 .->mmap 둘 이상의 프로그램들이 읽거나 쓸 수 있는 메모리 영역을 설정 .

Ch3. 파일다루기

Page 16: Linux programming study

프로세스와 신호에서 다루게 될 부분◦ 프로세스 구조 , 종류 , 일정◦ 새 프로세스를 시작하는 여러 가지 방법들◦ 부모 , 자식 , 좀비 프로세스◦ 신호와 그 활용 방법

프로세스란… ?◦ “ 하나 이상의 스레드들과 그 스레드들에 필요한 시스템 자원들을 포함하는 하나의 주소 공간”으로 정의한다 .◦ 프로세스를 현재 실행 중인 하나의 프로그램으로 간주 .

Ch11. 프로세스와 신호

Page 17: Linux programming study

프로세스 구조 , 종류 , 일정 ( 스케줄링 )

Ch11. 프로세스와 신호 PID 101

CODE

자료라이브러리

파일들

PID 102

CODE

자료라이브러리

파일들

code

C 라이브러리

Treck.txt nene.txt

$ grep 자료 treck.txt $ grep 자료 nene.txt

Page 18: Linux programming study

프로세스 보기Ch11. 프로세스와 신호

프로세스의 상태

현재 실행중인 프로세스

Page 19: Linux programming study

새 프로세스 시작◦ System 함수를 이용한 프로세스의 시작 . 여기선 clear 명령어를 사용했다 .

Ch11. 프로세스와 신호

Page 20: Linux programming study

프로세스 이미지 대체하기◦ Exec 함수를 이용 , 새 프로세스를 띄우지만 프로세스를 띄우는 방식이나 프로그램 인수들을 제공하는 방식은 서로 다르다 .

- System 함수보다 훨씬 효율적 -> 새 프로그램이 시작된 후에는 원래의 프로그램이 더 이상 실행될 필요가 없다는 점에서 system 함수보다 훨씬 효율적 .- 예 ) execl(const char* path, const char* arg0, … ,(char*)0);

Ch11. 프로세스와 신호

Execlp 를 이용한 ps ax 실행 .

Page 21: Linux programming study

프로세스의 이미지 복제 (fork)◦ 동시에 여러 기능을 수행하고자 할 때에는 제 12 장에서 다루는 스레드를 사용할 수도 있고 , init 이 하는 것처럼 한 프로그램 안에서 완전히 개별적인 프로세스를 생성 할 수도 있다 .

Ch11. 프로세스와 신호

초기 프로세스Fork()

원래 프로세스의 실행 새 프로세스

0 을 리턴새 PID 리턴

Page 22: Linux programming study

Fork 함수의 책에서의 간단한 예제Ch11. 프로세스와 신호

중간에 명령프롬프트가 껴있는데그 이유는 자식 프로세스는 여전히 실행 중 ,부모프로세스는 끝난 이유이다 .

Page 23: Linux programming study

좀비 프로세스◦ Fork 를 이용한 프로세스 생성은 유용하나 , 실행이 종료되었으나 부모와의 연관관계가 아직 남아 있는 프로세스를 가리켜서 소멸된 (defunct) 프로세스 , 좀비 프로세스라고 부른다 .

Ch11. 프로세스와 신호

실행 시 뒤에 & 붙여서 백그라운드 작업 후부모 프로세스 끝나기 전에 ps 명령어를 실행시켜보면 ,

<defunct> 라고 나오며 , 이것이 좀비 프로세스이다 .

Page 24: Linux programming study

쓰레드◦ 리눅스에서 프로세스보다 작은 실행 단위로 스레드라는 것이 있다 .추후 ch12 에서 다룸 .

신호 (signal)◦ 신호는 유닉스와 리눅스 시스템이 어떤 조건에 따라 발생시키는 사건이다 .

(event)◦ Signal 을 이용해서 프로세스를 관리한다 .◦ 많은 함수와 플래그 값이 있지만 나중에 사용시 레퍼런스 하는 것이 좋을거라 생각됨 .◦ 몇 가지 예만 설명하고 다음 장으로 .

Ch11. 프로세스와 신호

Page 25: Linux programming study

Signal◦ 헤더 파일은 <signal.h>◦ Signal 함수 , sigaction 함수가 있는데 둘 중 sigaction 함수가 더 효율성이 좋음 .( 안정성 , 신회성이 더 좋음 . )◦ 자주 쓰이는 신호

- SIGALRM – alarm 함수로 설정된 타이머에 의해 발생- SIGHUP – 연결 끊긴 터미널이 제어 프로세스에게 보냄- SIGINT – ctrl + c 또는 그에 해당하는 가로채기 문자가 입력 됬을 때- SIGKILL – 프로세스를 강제 종료하고자 할 때 .- SIGPIPE – 연관된 판독자가 없는 파이프에 쓰기 시도 시 발생 .- SIGTERM – kill 명령이 보내는 기본 신호- SIGUSR1, SIGUSER2 – 프로세스들이 서로 소통하는 데 쓰임- SIGCONT – 실행 재개- SIGCHLD – 자식 프로세스의 중지 , 종료 시 발생 .

Ch11. 프로세스와 신호

Page 26: Linux programming study

쓰레드란 ?◦ 한 프로그램의 여러 개의 실행 가닥들을 가리켜 쓰레드 (thread) 라고 부른다 .◦ 좀 더 정확하게 말하자면 쓰레드란 , 프로세스 안의 하나의 제어 흐름을 의미한다 .

◦ 쓰레드의 장 , 단점- 장점 : - - 자료처리량의 증대 , 여러 가지 일의 동시 처리를 통해 효율성증가- - 성능 향상- - 자원의 효율성 증가 .- 단점 :- - 다중 쓰레드 프로그램의 구현이 난이도가 높음- - 디버깅이 어렵다 .- - 다중처리 지원하는 다중 코어 컴퓨터이어야 함 .- 다중 쓰레드 프로그램의 예 ) 문서를 편집하는 동안 실시간으로 문자 수 세는 것 .

Ch 12. 쓰레드

Page 27: Linux programming study

첫 번째 다중 쓰레드 프로그램Ch 12. 쓰레드

Page 28: Linux programming study

쓰레드가 실행할 함수

-pthread_create 의 요구에 따라 , 이 함수는 void 포인터 하나를 받고 void 포인터를 돌려준다 . 헤더파일 <pthread.h> Int pthread_create(pthread_t* thread, pthread_attr_t* attr, void*(*start_routine)(void*), void* arg);1.pthread_t 를 가리키는 포인터 , 2. 쓰레드의 특성 , 3. Void 를 가리키는 포인터를 받고 void 를 가리키는 포인터를 돌려주는 함수의 주소 지정

Ch 12. 쓰레드

Page 29: Linux programming study

Main 함수

Res!=0 일 때는 thread 가 생성이 실패한 것 = exit, 성공 시 다음 printf 를 실행 . Res ==0 일 경우 res = pthread_join(a_thread, &thread_result); 실행 .

Ch 12. 쓰레드

Page 30: Linux programming study

동기화 두 쓰레드 이상이 동시에 실행될 때 , 쓰레드 실행을 제어하고 코드의 임계영역에 접근하기 위한 , 즉 좀 더 나은 쓰레드 실행을 제어 , 코드의 임계영역에 접근하기 위한 , 즉 좀 더 나은 쓰레드 실행 동기화를 위한 일단의 함수들이 존재한다 . - 세마포어 (Semaphore) : 코드영역 전후의 관문 역할을 한다 . -뮤텍스 (Mutex) : 코드영역을 보호하기 위한 상호 배제 수단 (Mutual exclusion) 으로 쓰임 . ※세마포어는 여러 개의 쓰레드를 동기화 할 때 사용하기 좋으며 , 뮤텍스는 하나 하나의 동기화를 할 때 좋다 . 간단한 예제

Ch 12. 쓰레드

Page 31: Linux programming study

쓰레드가 실행할 함수부분 .

글자 수를 세서 출력하는 함수 . 세마포어를 기다린 후 입력된 문자들의 개수를 셈 .

Ch 12. 쓰레드

세마포어 초기화 .(0 으로 )

Page 32: Linux programming study

End 문자 입력 시 종료 , FAST 입력 시 Wheee… 출력 .End 입력 시 쓰레드 종료 , 세마포어 해제 . 종료 .

Ch 12. 쓰레드

Page 33: Linux programming study

실행화면 .

Ch 12. 쓰레드

Page 34: Linux programming study

뮤텍스 (Mutex) 를 이용한 동기화 뮤텍스 (Mutex) 는 일정한 코드 영역이 한 번에 하나의 스레드에 의해서만 실행될 수 있도록 그 영역을 “잠그는” 역할을 한다 .( 코드 영역 == 임계영역 ) 해당영역의 동시접근을 막는다 . #include <pthread.h>Int pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexattr_t*Mutexattr); - 뮤텍스의 초기화Int pthread_mutex_lock(pthread_mutex_t* mutex); - 뮤텍스 잠금Int pthread_mutex_unlock(pthread_mutex_t* mutex); - 뮤텍스 해제Int pthread_mutex_destroy(pthread_mutex_t* mutex); - 뮤텍스 삭제* 동기화에 대한 부분은 세마포어와 뮤텍스를 통한 기법이 있다 정도만 있으면 된다 .* 차후에 프로그래밍 시 적용할 때는 각 함수를 레퍼런스하여 사용 .

Ch 12. 쓰레드

Page 35: Linux programming study

쓰레드의 특성 쓰레드의 특성 (attribute)

◦ 가장 중요한 함수는 쓰레드 특성 객체를 초기화하는 pthread_attr_init 이다 .이 함수는 성공 시 0 을 , 실패 시 -1 을 반환한다 .

쓰레드의 특성들◦ Detachedstate : 이 특성은 쓰레드의 재결합 가능 여부를 결정한다 .◦ Schedpolicy : 쓰레드의 일정 관리 방식을 결정한다 .(scheduling)◦ Schedparam : schedpolicy 에 추가적인 정보를 제공한다 .◦ Inheritsched : 쓰레드의 스케줄링 방식에 대해 설명한다 .( 해당특성 or 쓰레드를 만든 쓰레드의 방식 )◦ Scope : 쓰레드의 스케줄링을 계산하는 방식을 결정 .( 리눅스는 PTHREAD_SCOPE_SYSTEM 만 지원 )◦ Stacksize : 쓰레드 생성 스택 크기 결정 .

Ch 12. 쓰레드

Page 36: Linux programming study

쓰레드의 취소◦ 한 프로세스가 다른 프로세스에게 신호를 보내서 종료를 요청하듯 , 한 쓰레드가 다른 쓰레드에게 실행종료를 요청해야 하는 경우가 있다 . 이 때 쓰이는 함수는int pthread_cancel(pthread_t thread); // 유일한 인수는 쓰레드의 식별자이다 .

그전에 취소 상태를 결정해야 하는데 그 함수는Int pthread_setcancelstate(int state, int* oldstate);

* 자세한 상항은 따로 참조해서 보는것이 좋다 .

Ch 12. 쓰레드

Page 37: Linux programming study

두 개 이상의 쓰레드 여러 개의 새 쓰레드들을 생성해서 동시에 실행하는 예

Ch 12. 쓰레드

이 프로그램을 실행시키면 나오는 화면은…

Page 38: Linux programming study

실행화면Ch 12. 쓰레드

*책에서는 ‘ sleep 함수를 없애고 해보면 일부 쓰레드들이 같은 인수들로 시작되는 이상한 현상이 빚어진다’ 나온다 .이에 대한 문제는 쓰레드가 빠르게 실행되는 경우일부 쓰레드는 새로이 갱신된 지역변수의 값을 받게되고 , 그래서 같은 번호를 가진 쓰레드가 생기는 것 .-> 주소 값으로 받지말고 변수의 값을 스레드 함수에전달해야 한다 .

Page 39: Linux programming study

요약◦ 이번장에서만 요약을 쓰는 이유는 그만큼 쓰레드가 중요해서이다 .◦ 쓰레드는 프로세스의 단점을 보완해줄 수 있으며 , 여러방면에서 유용하다 . 하지만 구현이어렵다는게 단점이며 , 멀티 프로세스에서의 문제점인 동시 실행 문제나 동시 접근의 문제를 가지고 있다 . 윈도우즈 시스템 프로그래밍에서와 비슷하지만 함수관련하여 변수나 다른 부분만 다르지개념은 같다 .

책에서의 설명은 ,한 프로세스 안에서 여러 개의 쓰레드들을 생성하는 방법에 대해서 살펴 보았고 , 그러한 쓰레드들은 파일 범위 변수들을 함께 공유한다 . 또 그 공유하는 부분에 대해서 세마포와 뮤텍스를 이용 , 임계영역이나 자료에 대한 쓰레드의 접근을 제어하는 것도 보았다 .

Ch 12. 쓰레드

Page 40: Linux programming study

IPC : InterProcesscommunication 로 프로세스간 통신을 의미하며 그 중 파이프가 있다 . 파이프 (Pipe) : 두 프로세스 사이의 자료 흐름 통로를 제공 하는 수단 .일반적으로 파이프는 한 프로세스의 출력을 다른 프로세스의 입력에 연결하는 용도로 쓰인다 .

-popen, pclose – 두 프로그램이 자료를 주고 받는 가장 간단한 방법의 함수 .-pipe 함수 : 위의 popen, pclose 보다 저수준의 함수로 pipe 를 사용 시

fread 나 fwrite 같은 함수들이 아니라 read, write 같은 저수준 시스템 호출들을 사용해야 한다 .

*pipe 는 나중에… 중요도가 크지 않으므로…

Ch13. IPC : 파이프

Page 41: Linux programming study

명명된 파이프 :FIFO◦ Named pipe( 명명된 파이프 , 이름있는 파이프 )◦ 자식프로세스와 부모프로세스 관계의 파일 , 데이터 주고 받는 것과 달리 , 서로 연관되지 않은 프로세스들끼리 자료를 주고 받을 수 있게 하는 파이프

책에서 서버 & 클라이언트와의 연결을 FIFO 로 구현하였으며데이터베이스와의 연결 또한 FIFO 로 구현했는데 후에 소켓으로 구현하는 방법이 많이 사용되니 후에 소켓을 자세히 공부하기로 했다 .

Ch13. IPC : 파이프

Page 42: Linux programming study

세마포 (semaphore) 란 ?◦ 하나의 자원에 단 하나의 프로세스 ( 또는 프로세스 ) 만이 접근함을 보장해야 하는 코드 영역이 있는데 , 그런 영역을 임계 영역 (critical section) 이라고 부른다 .여러 프로그램들이 하나의 공유 자원에 동시에 접근할 때 발생하는 문제를 방지하려면 한 번에 단 하나의 실행 쓰레드만 하나의 임계영역에 접근할 수 있도록 일종의 토큰을 생성 , 부여하는 수단이 필요하다 .세마포를 이용 , 임계 영역에 접근하는 것을 통제 , 동기화 한다 .

세마포는 오직 대기 (wait), 신호 (signal) 라는 두 가지 연산만이 가능한 특별한 변수라고 할 수 있다 . ex) 가장 간단한 세마포는 이진 세마포인데 0, 1 값 만을 가진다 .

Ch14. 세마포 , 공유 메모리 . 메시지 큐

Page 43: Linux programming study

세마포의 사용◦ 책에서는 semaphore_p, semaphore_v 함수를 만들어서 ,

semaphore_p 는 세마포 값을 -1 만큼 변경하게 하며 ( 대기 )semaphore_v 는 세마포 값을 +1 만큼 변경하게 하여 ( 신호 )

임계영역에 들어갈 때는 semaphore_p 를 , 나올 때는 semaphore_v 를호출하여 임계 영역에 대한 접근을 동기화한다 .이 함수들은 좀 더 일반적인 semop 함수를 단순화한 인터페이스다 . 세마포를 사용한 후에는 삭제하는 것이 좋은데 , 프로그램을 다음에 다시 실행할 때 문제가 생길 수 있기 때문이다 .

Ch14. 세마포 , 공유 메모리 . 메시지 큐

Page 44: Linux programming study

공유 메모리 (Shared Memory)◦ IPC 수단이며 , 서로 무관한 두 프로세스가 동일한 논리적 메모리 영역에 접근할 수 있게 한다 . 공유 메모리를 이용하면 실행 중인 두 프로세스가 자료를 아주 효율적인 방식으로 주고받을 수 있다 .

IPC 가 한 프로세스를 위해 생성한 공유 메모리는 그 프로세스의 주소 공간에서 특정 범위를 차지한다 .공유 메모리는 여러 프로세스들이 자료를 공유하고 주고받는 효율적인 수단이 된다 . 이 때 , 공유 메모리 자체는 동기화 수단을 제공하지 않아서 해당 프로그램이 책임져야 한다 .* 함수 )-shmget : 공유 메모리 생성 / 변수 : (key_t key,size_t size,int shmflg)-shmat : 프로세스의 주소공간에 부착-shmdt : 공유 메모리를 현재 프로세스에서 떼어낸다 .(detach)-shmctl : 공유 메모리를 제어하는 용도 ( 공유메모리 식별자 , 명령 , 공유메모리의 모드들과 권한들을 담은 구조체 포인터 )

Ch14. 세마포 , 공유 메모리 . 메시지 큐

Page 45: Linux programming study

메시지 큐 (Message queue)◦ IPC 의 한 방법으로 명명된 파이프와 여러모로 비슷한 반면 , 파이프를 열고 닫는 데 관련된 번잡함이 없다 . 그러나 꽉 찬 파이프에 의한 실행 차단 등 명명된 파이프에서 발생할 수 있는 문제들은 메시지 큐에도 여전히 존재한다 .메시지 큐를 이용하면 서로 무관한 두 프로세스가 자료를 상당히 쉽고 효율적으로 주고 받을 수 있다 . 명명된 파이프와 달리 메시지 큐는 전송 프로세스와 수신 프로세스 모두에 독립적으로 존재한다 . 이 덕분에 파이프에서 열기와 닫기를 동기화할 때 생기는 어려움을 피할 수 있다 .

- 한 프로세스가 다른 프로세스에게 자료 블록을 전달하는 수단 . 각 자료 블록이 자신의 종류를 구분하는 값을 가지고 있어서 수신 프로세스는 서로 다른 종류의 자료 블록들을 독립적으로 받을 수 있고 , 처리가 복잡해질 수 있다 .또 파이프와 마찬가지로 각 자료 블록의 크기에는 상한이 존재하며 , 시스템 전반의 모든 대기열에 담을 수 있는 블록들의 전체 크기에도 상한이 존재한다 .

Ch14. 세마포 , 공유 메모리 . 메시지 큐

Page 46: Linux programming study

메시지 큐 함수◦ #include <sys/msg.h>

int msgctl(int msgid, int cmd, struct msgid_ds* buf);int msgget(key_t key, int msgflg);int msgrcv(int msgid, void* msg_ptr, size_t msg_sz, long int msgtype, int msgflg);int msgsnd(int msgid, const void* msg_ptr, size_t msg_sz, int msgflg);

< 함수 >Msgget : 메시지 큐에 접근할 때 사용하는 함수 .Msgsnd : 메시지 큐에 하나의 메시지를 전송할 때 사용하는 함수 .Msgrcv : 메시지 큐에서 메시지를 받을 때 사용하는 함수 .Smgctl : 메시지 큐를 제어하는 함수 .( 공유 메모리의 제어 함수와 아주 비슷 )

Ch14. 세마포 , 공유 메모리 . 메시지 큐

Page 47: Linux programming study

각각의 IPC 상태보는 명령어 ( 터미널 창에서 )◦ 세마포 상태 보기

- ipcs –s

◦ 공유 메모리 상태 보기- ipcs –m

◦ 메시지 큐 상태 보기- ipcs -q

Ch14. 세마포 , 공유 메모리 . 메시지 큐

Page 48: Linux programming study

소켓이란 ..?◦ Ch13, 14 장에서 다루었던 것과 근본적인 차이를 보인다 . 소켓에서는 여러 컴퓨터들의 경계를 넘나들 수 있다 .소켓의 사용 방법은 파이프 사용 방법과 매우 비슷하지만 , 여러 컴퓨터들의 네트워크를 가로질러서 자료를 주고받을 수 있는 능력은 소켓에만 해당된다 . 한 컴퓨터의 프로세스는 소켓을 통해서 다른 컴퓨터의 프로세스와 통신할 수 있으며 , 이를 통해서 네트워크상에 분산된 클라이언트 / 서버 시스템을 구축할 수 있다 .

ex) 원격 인쇄 , 데이터베이스 연결 , 웹 서버 기능 등 .

◦ * 소켓 인터페이스는 Windows 도 지원하며 , 윈속 (WinSock)이라고 부른다 .

Ch15. 소켓

Page 49: Linux programming study

주제◦ 소켓 연결의 작동 방식◦ 소켓의 특성들과 주소 , 통신◦네트워크 정보와 인터넷 데몬◦클라이언트와 서버

Ch15. 소켓

Page 50: Linux programming study

소켓 연결◦ 1. 서버 응용프로그램이 소켓을 생성한다 . 서버는 시스템 호출 socket 을 이용 , 소켓을 생성 .( 이 소켓은 다른 프로세스와 공유되지 못한다 .◦ 2. 서버 프로세스는 그 소켓에 하나의 이름을 부여한다 . 네트워크 소켓의 경우 클라이언트가 연결할 수 있는 특정 네트워크에 관련된 서비스 식별자가 부여된다 .소켓에 이름을 부여할 때 사용하는 시스템 호출은 bind 이다 . 이름을 부여한 후 , 서버 프로세스는 해당 소켓에 클라이언트가 연결되기를 기다린다 . 이를 위한 시스템 호출은

listen 이며 , 이 함수는 들어오는 연결을 위한 대기열을 생성한다 . 연결 요청이 들어오면 서버는 시스템 호출 accept 를 이용해서 그 요청을 받아들인다 .서버가 accept 를 호출하면 , 명명된 소켓과는 개별적인 새로운 소켓이 생성된다 .이 새 소켓은 해당 클라이언트 하나와의 통신에만 쓰인다 .

-클라이언트 쪽의 소켓 기반 시스템은 훨씬 간단하다 . 클라이언트는 socket 을 호출해서 이름없는 소켓을 생성 , 그 다음에는 서버의 명명된 소켓을 주소로 사용해 connect 를 호출함으로써 서버와의 연결을 만든다 .

Ch15. 소켓

Page 51: Linux programming study

소켓 특성들 .◦ 소켓을 규정하는 가장 중요한 특성 세 가지는 도메인 , 종류 , 프로토콜 이다 .◦ 소켓은 또한 주소로 쓰이는 이름도 가지는데 , 주소의 형식은 도메인에 따라 다르다 .◦ 도메인을 프로토콜 패밀리라고 부르기도 한다 .

◦ 소켓 도메인 .- 도메인은 소켓 통신이 사용할 네트워크 매체를 결정한다 . 가장 흔히 쓰이는 소켓 도메인은

AF_INET 으로 , 이것은 인터넷 자체는 물론 여러 리눅스 근거리 통신망에도 쓰이는 인터넷 네트워킹에 해당한다 . 이 도메인의 프로토콜 패밀리는 인터넷 프로토콜 (IP) 이다 .인터넷 프로토콜에서 네트워크상의 특정한 컴퓨터를 지칭하는 데 쓰이는 주소 형식은 IP 주소 하나뿐이다

Ch15. 소켓

Page 52: Linux programming study

소켓의 종류◦ 스트림 소켓

- 표준 입 , 출력 스트림과 다소 비슷한 면을 가진 스트림 소켓은 순차적인 , 그리고 신뢰성 있는 양방향 바이트 스트림 방식의 연결을 제공한다 .( 신뢰성 : 전송된 자료가 오류가 보고되지 않고 소실되거나 , 복제되거나 , 순서가 바뀌는 일은 없다는 뜻 )◦ 데이터그램 소켓

- 연결의 유지 및 관리를 수행하지 않는다 . 또한 이 종류의 소켓에서 보낼 수 있는 하나의 데이터그램의 크기에는 한계가 주어져 있다 . 데이터그램은 도중에 소실되거나 , 중복되거나 , 다른 데이터그램과 순서가 바뀔 수 있다 . (UDP/IP 연결을 통해 구현된다 .)- 순차성과 신뢰성을 보장하진 않지만 , 네트워크 연결을 유지할 필요가 없기 때문에 자원 효율성이 좋다 . 연결 설정하는데 소요 시간이 없기 때문에 속도도 빠르다 .

◦ 소켓 프로토콜- 소켓 종류의 전송 메커니즘이 여러 개의 프로토콜들을 제공하는 경우 프로그램은 그 중 하나를 선택할 수 있다 . 책에서는 다른 소켓 프로토콜은 사용하지 않았다 .

Ch15. 소켓

Page 53: Linux programming study

소켓 생성◦ int socket(int domain, int type, int protocol);

- domain 은 소켓의 주소 패밀리를 결정- type 는 소켓에 쓰일 통신의 종류를 결정 .- protocol 은 그 통신을 위한 프로토콜을 결정 .- Socket 시스템 호출은 하나의 서술자를 돌려주는데 , 이것은 저수준 파일 시스템 서술자와 여러모로 비슷하다 .- 소켓이 연결되면 이 서술자로 시스템 호출 read, write 를 호출 , 자료를 읽거나 쓸 수 있다 . 소켓 연결을 끝낼 때에는 close 사용 .

Ch15. 소켓

Page 54: Linux programming study

소켓 이름 붙이기◦ int bind(int socket, const struct sockaddr* ad-

dress, size_t address_len);

- Bind 시스템 호출은 socket 변수로 지정된 이름 없는 소켓에 address 매개변수로 지정된 주소 구조체에 담긴 주소를 부여한다 .- Bind 를 호출할 때에는 특정 주소 구조체 포인터를 반드시 일반적인 주소 형식 포인터

(struct sockaddr*) 로 강제 형변환해야 한다 .- bind 는 성공 시 0 을 , 실패 시 -1 을 반환 .

Ch15. 소켓

Page 55: Linux programming study

소켓 연결 대기열 만들기◦ int listen(int socket, int backlog);

- backlog 변수는 listen 이 생성할 대기열의 크기 , 즉 대기열에 담을 수 있는 연결 요청들의 최대 개수이다 .- listen 함수는 성공 시 0 을 , 실패 시 -1 을 돌려준다 .

Ch15. 소켓

Page 56: Linux programming study

연결 수락◦ Int accept(int socket, struct sockaddr* address, size_t* address_len);Accept 시스템 호출은 socket 변수로 지정된 소켓에 클라이언트가 연결을 시도하길 기다린다 . 그 클라이언트는 소켓의 대기열의 첫 번째 연결 요청에 해당한다 . accept 는 그 클라이언트의 통신을 위한 새 소켓을 생성한 후 그것의 서술자를 반환한다 . 새 소켓은 서버의 청취 소켓과 같은 종류이다 .

- socket 변수에는 반드시 bind 로 명명 , listen 으로 대기열을 만든 소켓의 서술자를 지정해야 한다 .-address 변수가 가리키는 곳에는 연결된 클라이언트의 주소 구조체가 설정된다 .-address_len 변수에는 클라이언트 주소 구조체의 길이를 담은 변수의 주소 설정 .

* 소켓의 대기열에 연결 요청이 하나도 없으면 accept 호출이 차단되며 , 클라이언트가 연결을 요청하면 비로소 서버 프로세스의 실행이 재개된다

Ch15. 소켓

Page 57: Linux programming study

연결 요청◦ int connect(int socket, const struct sockaddr* address,

size_t address_len);- Socket 변수는 클라이언트쪽 소켓의 서술자이고 address 는 서버쪽 소켓의 주소를 담은 구조체를 가리킨다 .- Address_len 은 그 구조체의 길이이다 .- Socket 변수에는 반드시 socket 호출로 얻은 유효한 서술자를 지정해야한다 .- connect 는 성공시 0, 실패시 -1 을 돌려준다 .

소켓 닫기◦ Close 를 호출해서 소켓연결을 끝낼 수 있다 .

Ch15. 소켓

Page 58: Linux programming study

다중 클라이언트◦ 하나의 서버에 여러 개의 클라이언트들이 동시에 연결하는 경우 .

- 서버 프로그램 측에서 fork 를 이용 , 다중 클라이언트를 처리할 수도 있으며 select 함수를 이용하여 처리 할 수도 있다 .- 여기서 select 란 , 시스템 호출로써 저수준 파일 서술자들을 하나의 단위로 취급해서 그것들 중 하나에 입력이 들어오기를 ( 또는 출력이 완료되길 ) 기다릴 수 있다 . 만약 다중 클라이언트에서 사용한다면 , 서버 쪽 청취 소켓과 클라이언트 연결 소켓 모두를 동시에 기다린다 . 둘 중 하나라도 활동이 감지되면 , 모든 가능한 파일 서술자를 점검 , 어떤 소켓이 깨어났는지 파악 , 그에 따라 적절한 처리를 수행한다 .- 서버 쪽 청취 소켓에 입력이 들어왔다면 어떤 클라이언트가 서버와의 연결을 시도한 것이다 . 이 경우 차단을 걱정하지 않고 accept 를 호출 할 수 있다 .

Ch15. 소켓

Page 59: Linux programming study

간단한 실습 (client 쪽 , client1.c)

Ch15. 소켓그냥 client1 만 실행시키면 ,

Server 와 같이 실행시키면

Page 60: Linux programming study

간단한 실습 (server1.c 서버 쪽 )

Ch15. 소켓./server1 & 을 입력 , server1 을백그라운드 작업하여 client1 을 실행시키는데 ,./server1 & 후 ps 의 상태는 ,

그리고 서버는 파일 시스템상의 소켓을생성하는데 그 파일은 ls 명령으로 볼 수 있다

다 사용한 소켓은 제거하는 것이 좋다 .( 프로그램이 신호에 의해서 비정상적으로종료되었다면 , 소켓이 남아 있는지 확인 , 제거해야 파일 시스템이 지저분해지는 것을피할 수 있다 .

Page 61: Linux programming study

간단한 실습에 대한…

◦ 서버는 클라이언트가 기록한 문자 하나를 읽어서 그것을 증가한 후다시 클라이언트에게 보낸다 .( 출력하는 건 클라이언트 측 )

Ch15. 소켓

Page 62: Linux programming study

더 상세히 공부하고 싶었지만 처음 책을 정독한것에대해 만족을 하며 , 프로그래밍을 할 때 , 다시 책을 볼 때 , 좀 더 코드 부분과 직접 프로그래밍하는거에 중점을 둘 필요가 있다고 생각이 드는 공부였다 .그리고 중요하다고 생각되는 부분만 공부하였는데 차후에 공부할 때에는 다른 부분도 공부를 해야겠다 . 또 소켓 프로그래밍 같은 부분은 따로 책이 있으니 그 부분에 대해서 더 공부할 필요성이 느껴진다 .

개인 스터디를 마치며

Page 63: Linux programming study

Thank you[Pineoc] - 이윤석