강의
Linux
•
서버 + 클라우드 컴퓨팅에 많이 사용되는 운영체제
•
프로그래밍을 할 때에도 많이 사용되는 운영체제
◦
운영체제, 소프트웨어의 대부분 Unix 계열 운영체제
◦
ANSI C (C언어 표준)를 따르므로 plain하게 프로그래밍 가능
Linux의 역사
•
GNU (Gnu is Not Unix) 프로젝트
◦
Unix 운영체제를 여러 회사에서 각자 개발하고 소스를 공유하지 않음
◦
1985년 리차드 스톨만이 GNU 선언문을 발표 (초기 컴퓨터 개발 공동체의 상호협력적인 문화로 돌아갈 것을 주장)
◦
GNU 프로젝트를 지원하기 위해 자유 소프트웨어 재단(FSF) 설립과 GNU 공개 라이센스(GPL) 규약을 제공
•
GPL 라이센스
◦
GPL 프로그램은 어떤 목적으로, 어떤 형태로든 사용할 수 있지만 사용하거나 변경된 프로그램을 다시 배포하는 경우 동일한 GPL 라이센스로 공개해야함
◦
소스 오픈을 장려하기 위함
•
GNU Hurd
◦
운영체제 커널 개발 시도
◦
운영체제에 필요한 라이브러리, 컴파일러, 에디터, 쉘 개발
◦
GNu Hurd의 개발 지연
•
GNU/Linux
◦
Linus Torvalds가 다중 사용자, 다중 작업(시분할 시스템, 멀티 태스킹)을 지원하는 Unix와 유사한 운영체제 개발 후 소스 오픈
◦
Linux 커널 소스 오픈으로 인해 GNU 프로젝트와 Linux 커널이 통합 개발
Linux 배포판(패키지)
•
리눅스 커널 및 다양한 소프트웨어 패키지를 묶어서 배포하는 것
Linux 기본구성
•
Linux와 프로세스
◦
ELF(Executable and Linkable Format)라는 리눅스 실행 파일 포멧을 가짐
◦
콜스택, 코드(텍스트), 데이터 및 BSS 섹션 등 Unix와 유사한 프로세스 구조
◦
시스템콜 기반 리소스(타이머, 시그널, 파일, 네트워크, 디바이스, IPC기법 등)를 처리 가능하도록 구성
◦
가상 메모리 지원
◦
각 프로세스는 pic(프로세스ID) 고유값으로 구분
◦
init 프로세스(첫번째 프로세스)를 기반으로 fork() 시스템콜을 사용해서 신규 프로세스가 생성
•
Linux와 권한
◦
운영체제는 사용자/리소스로 권한을 관리
◦
리눅스는 사용자/그룹으로 권한을 관리
◦
파일마다 소유자, 소유자 그룹, 모든 사용자에 대해 읽고 쓰고 실행하는 권한을 inode 자료구조에 저장하여 관리
◦
root는 슈퍼관리자
•
Linux와 파일
◦
모든 것은 파일이라는 철학을 따름
▪
모든 인터랙션은 파일을 읽고 쓰는 것처럼 이루어져있음
▪
마우스, 키보드와 같은 모든 디바이스 관련된 기술도 파일과 같이 다루어짐
▪
모든 자원에 대한 추상화 인터페이스로 파일 인터페이스를 활용
◦
파일은 inode 고유값과 자료구조에 의해 주요 정보 관리
◦
파일 네임스페이스
▪
전역 네임스페이스 사용
•
루트 디렉토리(/)를 사용 (윈도우는 A 드라이브 A:/ , C 드라이브 C:/ 등을 사용)
▪
/home
•
사용자 이름을 가진 디렉토리 존재
▪
/media , /mnt
•
Floofy, SSD와 같은 추가적인 저장매체를 연결 시 관련 파일
▪
/etc
•
각 설정에 관련된 파일
▪
/dev
•
마우스, 키보드와 같은 디바이스 연결 시 관련 파일
▪
/bin , /sbin
•
쉘 명령어 실행파일
▪
/boot
•
운영체제 부팅과 관련된 파일
▪
/var/log
•
로그 관련 파일
쉘 (Shell)
•
쉘이란?
◦
사용자와 컴퓨터 하드웨어 또는 운영체제 간 인터페이스
◦
사용자의 명령을 해석해서 커널에 명령을 요청해주는 역할
◦
관련된 시스템콜을 사용해서 프로그래밍이 작성되어 있음
◦
Linux 명령어는 결국 쉘이 제공하는 명령어
•
종류
◦
Bourne Shell (sh)
◦
C Shell (csh)
◦
Bourne-Again Shell (bash)
▪
GNU 프로젝트의 일환으로 개발됨 (Linux의 기본 쉘)
◦
Korn Shell (ksh)
▪
Unix에서 많이 사용
쉘 명령어
•
whoami
◦
로그인한 사용자 ID를 알려줌
•
passwd
◦
로그인한 사용자 ID의 암호 변경
•
useradd , adduser
◦
사용자를 추가
◦
useradd : 사용자 기본 설정을 자동으로 하지 않음
◦
adduser : 사용자 기본 설정을 자동으로 수행함
•
sudo
◦
root 계정으로 로그인 하지 않은 상태에서 root 권한이 필요한 명령을 실행하기
◦
/etc/sudoers 설정 파일을 통해 sudo를 사용할 수 있는 사용자를 지정 가능
# 특정 사용자가 sudo를 사용할 수 있도록 설정
userid ALL=(ALL) ALL
# 특정 그룹에 포함된 모든 이용자가 sudo를 사용할 수 있도록 설정
%group ALL=(ALL) ALL
# 패스워드 생략 설정
userid ALL=(ALL) NOPASSWD: ALL
%group ALL=(ALL) NOPASSWD: ALL
Bash
복사
•
su
◦
사용자를 변경
◦
su root : 현재 사용자의 환경설정 기반으로 사용자 변경
◦
su - root : 변경되는 사용자의 환경설정 기반으로 사용자 변경
•
pwd
◦
현재 디렉토리의 위치 확인
•
cd
◦
디렉토리 이동
◦
cd ~ : 홈 디렉토리로 이동
•
ls , dir
◦
파일 목록 출력
◦
ls -al : 숨김 파일과 함께 파일의 세부정보까지 출력
◦
ls file* : 이름 앞에 file이 붙은 파일 목록 출력 (와일드 카드 사용 가능)
•
man
◦
명령어의 사용법 확인
•
chmod
◦
파일 권한 변경
◦
chmod u+rw : 기호 문자를 사용하는 방법
◦
chmod 777 : 숫자를 사용하는 방법
◦
chmod -R 777 directory : 하위 디렉토리에 전부 파일 권한 변경
•
chown
◦
파일 소유자, 소유그룹 변경
◦
chown [옵션] [소유자:소유그룹] [파일]
•
chgrp
◦
파일 소유그룹만 변경
◦
chgrp [옵션] [소유그룹] [파일]
•
cat
◦
파일 보기
•
head , tail
◦
head -n 3 : 파일 시작 3줄을 보여줌 (기본값 10줄)
◦
tail -n 3 : 파일 끝 3줄을 보여줌 (기본값 10줄)
•
more
◦
화면이 넘어갈 경우 화면이 넘어가기 전까지 파일을 보여줌
•
rm
◦
파일 삭제
◦
rm -rf : 하위 디렉토리를 포함한 모든 파일 강제 삭제
•
grep
◦
검색
◦
grep [-option] [pattern] [file or directory name]
▪
-i : 영문의 대소문자를 구별하지 않는다.
▪
-v : pattern을 포함하지 않는 라인을 출력한다.
▪
-n : 검색 결과의 각 행의 선두에 행 번호를 넣는다.
▪
-l : 파일명만 출력한다.
▪
-c : 패턴과 일치하는 라인의 갯수만 출력한다.
▪
-r : 하위 디렉토리까지 검색한다.
•
bg
◦
suspend 모드의 프로세스를 background process로 실행
•
jobs
◦
suspend 모드 또는 background process를 보여줌
•
ps
◦
프로세스 상태 확인
◦
ps [option(s)]
▪
-a : 시스템을 사용하는 모든 사용자의 프로세스 출력
▪
-u : 프로세스 소유자에 대한 상세 정보 출력
▪
-l : 프로세스 관련 상세 정보 출력
▪
-x : 터미널에 로그인한 후 실행한 프로세스가 아닌 프로세스들(데몬)도 출력
▪
-e : 해당 프로세스와 관련된 환경 변수 정보도 함께 출력
▪
-f : 프로세스 간 관계 정보도 출력
•
kill
◦
프로세스 중지
◦
kill [option] [pid]
▪
-9 : 강제 종료
•
cp
◦
파일 복사
◦
cp -rf : 하위 디렉토리를 포함한 모든 파일 강제로 복사
•
ln
◦
링크 파일 생성
◦
ln : 하드 링크 파일 생성
◦
ln -s : 소프트 링크(심볼릭 링크) 파일 생성
•
ipcs
◦
생성된 IPC 기법 자원 확인
Redirection과 Pipe
•
Standard Stream (표준 입출력)
◦
command로 실행되는 프로세스는 세 가지 스트림을 가지고 있음
▪
표준 입력 스트림 (Standard Input Stream) - stdin
▪
표준 출력 스트림 (Standard Output Stream) - stdout
▪
에러 출력 스트림 (Standard Error Stream) - stderr
◦
모든 스트림은 일반적인 plain text로 colsole에 출력
•
Redirection (리다이렉션)
◦
표준 스트림 흐름을 바꿔줄 수 있다.
◦
주로 명령어 표준 출력을 화면이 아닌 파일에 쓸 때 사용
◦
> , < : 새로운 파일 생성 또는 덮어쓰기
◦
>> , << : 기존 파일 끝에 추가
•
Pipe (파이프)
◦
두 프로세스 사이에서 한 프로세스의 출력 스트림을 또 다른 프로세스의 입력 스트림으로 사용할 때 사용
Hard Link와 Soft Link
•
Hard Link
◦
하드 링크는 같은 inode 번호를 갖는 파일을 생성하므로 파일의 모든 정보는 동일
◦
원본 파일을 삭제하더라도 하드 링크 파일은 접근 가능
•
Soft Link
◦
소프트 링크는 다른 inode 번호를 갖지만 원본 파일의 주소를 가진 파일을 생성
◦
원본 파일을 삭제하면 소프트 링크 파일에 접근 불가능
쉘 스크립트 (Shell Script)
•
쉘 스크립트란?
◦
쉘을 사용해서 프로그래밍을 할 수 있음
◦
서버 작업 자동화 및 운영(DevOps)을 위해 기본적으로는 익혀둘 필요가 있음
◦
쉘 명령어를 기본으로 하되, 몇 가지 문법이 추가된 형태
◦
시스템 프로그래밍에서 꼭 익히는 내용 중 하나
•
기본 문법
◦
쉘 스크립트는 파일로 작성 후 파일을 실행
◦
파일의 가장 위의 첫 라인은 #!/bin/bash로 시작
◦
쉘 스크립트 파일은 chmod +x 을 통해 실행권한을 부여해야함
◦
일반적으로 파일이름.sh 와 같은 형태로 파일 이름을 작성함
•
변수
var="value"
echo ${var}
Bash
복사
◦
선언
▪
변수명=데이터 (띄어쓰기 X)
◦
사용
▪
$변수명
•
리스트 변수 (배열)
vars=("values1" "value2" "value3")
echo ${vars[0]} #배열의 첫번째 인덱스에 해당하는 값 출력
echo ${vars[@]} #배열의 모든 데이터 출력
echo ${vars[*]} #배열의 모든 데이터 출력
echo ${#vars[@]} #배열의 크기 출력
filelist=( $(ls) ) #ls 커맨드의 output을 filelist 변수에 입력
Bash
복사
◦
선언
▪
변수명=(데이터1 데이터2 데이터3)
◦
사용
▪
${변수명[인덱스번호]}
•
사전에 정의된 지역 변수
◦
$$ : 쉘의 프로세스 번호 (PID)
◦
$0 : 쉘스크립트 이름
◦
$1 ~ $9 : 명령줄 인수
◦
$* : 모든 명령줄 인수리스트
◦
$# : 인수의 개수
◦
$? : 최근 실행한 명령어의 종료값
▪
0 : 성공
▪
1 ~ 125 : 에러
▪
126 : 파일이 실행가능하지 않음
▪
128 ~ 255 : 시그널 발생
•
연산자
num=`expr \ ( 3 \* 5 \) / 4 + 7`
echo $num
Bash
복사
◦
expr : 숫자 계산
◦
따옴표 주의
◦
연산자와 괄호 앞에는 역슬래시(\)와 같이 사용
◦
연산자와 숫자, 변수, 기호 사이에는 space를 넣어야함
•
조건
문자1 == 문자2 #문자1과 문자2가 일치
문자1 != 문자2 #문자1과 문자2가 불일치
-z 문자 #문자가 null이면 참
-n 문자 #문자가 null이 아니면 참
값1 -eq 값2 #값이 같음(equal)
값1 -ne 값2 #값이 같지 않음(not equal)
값1 -lt 값2 #값1이 값2보다 작음(less than)
값1 -le 값2 #값1이 값2보다 작거나 같음(less or equal)
값1 -gt 값2 #값1이 값2보다 큼(greater than)
값1 -ge 값2 #값1이 값2보다 크거나 같음(greater or equal)
-e 파일명 #파일이 존재하면 참
-d 파일명 #파일이 디렉토리면 참
-h 파일명 #심볼릭 링크파일이면 참
-f 파일명 #파일이 일반파일이면 참
-r 파일명 #파일이 읽기 가능이면 참
-s 파일명 #파일 크기가 0이 아니면 참
-u 파일명 #파일이 set-user-id가 설정되면 참
-w 파일명 #파일이 쓰기 가능이면 참
-x 파일명 #파일이 실행 가능이면 참
조건1 -a 조건2 #AND
조건1 -o 조건2 #OR
조건1 && 조건2 #양쪽 다 성립
조건1 || 조건2 #한쪽 또는 양쪽 다 성립
!조건 #조건이 성립하지 않음
true #조건이 언제나 성립
false #조건이 언제나 성립하지 않음
Bash
복사
•
조건문
if [ 조건 ]
then
명령문
else
명령문
fi
Bash
복사
if [ 조건 ]; then 명령문; fi
Bash
복사
◦
[] 에서 &&, ||, <, > 연산자들이 에러가 나는 경우는 [[]]를 사용하면 정상 작동하는 경우가 있음
•
반복문
for 변수 in 변수값1 변수값2 ...
do
명령문
done
Bash
복사
while [ 조건문 ]
do
명령문
done
Bash
복사
•
기타 명령
ping -c 192.168.0.1 1> /dev/null
Bash
복사
◦
-c
▪
한 번만 체크
◦
1> /dev/null
▪
0 : 표준 입력, 1 : 표준 출력, 2 : 표준 에러
▪
표준 출력 내용은 버려라 (출력하지 말아라)
시스템 콜
•
시스템 콜이란?
◦
운영체제 리소스나 서비스 요청을 위해 사용자 영역에서 커널 영역으로 들어가는 함수
•
주요 시스템 콜
◦
read(), write(), open() 등
•
시스템 콜은 어떻게 구현?
mov eax, 1
mov ebx, 0
int 0x80 //소프트웨어 인터럽트 명령
Shell
복사
◦
eax 레지스터에 시스템 콜 번호를 넣고
◦
ebx 레지스터에는 시스템 콜에 해당하는 인자값을 넣고
◦
소프트웨어 인터럽트 명령을 호출하면서 0x80 값을 넘겨줌
◦
CPU는 사용자 모드를 커널 모드로 바꿔줌
◦
IDT(Interrupt Descriptor Table)에서 0x80에 해당하는 주소(함수)를 찾아서 실행함
◦
system_call() 함수에서 eax로부터 시스템 콜 번호를 찾아서 해당 번호에 맞는 시스템 콜 함수로 이동
◦
해당 시스템 콜 함수 실행 후 다시 커널 모드에서 사용자 모드로 변경하고 다시 해당 프로세스 다음 코드 진행
API와 ABI
•
API(Application Programming Interface)란?
◦
응용 프로그램과 분리된 하위 호환 인터페이스
◦
ex) 시스탬 콜 래퍼, 입출력 라이브러리 등
•
ABI(Application Binary Interface)란?
◦
응용 프로그램 바이너리 인터페이스
◦
함수 실행 방식, 레지스터 활용, 시스템 콜 실행, 라이브러리 링크 방식 등을 정의
◦
ABI가 호환되면 재컴파일 없이 동작
◦
컴파일러, 링커(라이브러리 링크), 툴체인(컴파일러를 만드는 프로그램)에서 제공
•
C 라이브러리
◦
유닉스 C 라이브러리 : libc
◦
리눅스 C 라이브러리 : glibc (GNU libc)
◦
시스템 콜, 시스템 콜 래퍼, 기본 응용 프로그램 기능 포함
•
C 컴파일러
◦
유닉스 C 컴파일러 : cc
◦
리눅스 C 컴파일러 : gcc (GNU cc)
POSIX와 ANSI C
•
POSIX란?
◦
유닉스 시스템 프로그래밍 인터페이스 표준
◦
IEEE(Institute of Electronic and Electronics Engineers)에서 표준화 시도
◦
리차드 스톨만(자유 소프트웨어 재단)이 POSIX를 표준안 이름으로 제안
•
ANSI C란?
◦
다양한 C 언어의 변종으로 인해 생겨난 C 언어의 표준
◦
ANSI(American National Standards Institute)에서 표준 정립
프로그램, 프로세스, 스레드
•
프로그램 (바이너리)
◦
바이너리, 코드 이미지, 응용 프로그램, Application 또는 실행 파일
•
프로세스
◦
실행 중인 프로그램 (메모리 적재 + 프로세스 상태 정보 포함)
▪
가상 메모리 및 물리 메모리 정보
▪
시스템 리소스 관련 정보
▪
스케줄링 단위
◦
PID (Process ID)
▪
각 프로세스는 해당 시점에 unique한 pid를 가짐
▪
pid의 최대 값은 2^15 = 32768
▪
부호형(signed) 16비트 정수값 사용
◦
프로세스 계층
▪
init 프로세스(최초 프로세스)의 pid는 1
▪
init 프로세스는 운영체제가 생성
▪
다른 프로세스는 또 다른 프로세스로부터 생성 (부모, 자식 프로세스)
▪
ppid 값이 부모 프로세스의 pid를 뜻함
•
스레드
◦
리눅스 프로세스는 기본 스레드 포함
◦
싱글 스레드 프로세스 : 기본 프로세스
◦
멀티 스레드 프로세스 : 여러 스레드 존재
Foreground process와 Background process
•
Unix의 철학
◦
여러 프로그램이 서로 유기적으로 각자의 일을 수행하면서 전체 시스템이 동작하도록 하는 모델
◦
Linux는 기본적으로 다양한 프로세스가 실행됨
•
Foreground process
◦
프로세스를 실행한 후 해당 프로세스 수행 종료까지 사용자가 다른 입력을 하지 못하는 프로세스
◦
CTRL + C : foreground process를 작업 취소(종료)
◦
CTRL + Z : foreground process를 실행 중지 상태(suspend 모드)로 변경
•
Background process
◦
사용자 입력과 상관없이 실행되는 프로세스
◦
쉘에서 해당 프로세스 실행 시 맨 뒤에 &를 붙여줌
프로세스 생성과 종료
•
기본 프로세스 생성 과정
◦
TEXT, DATA, BSS ,HEAP, STACK의 공간을 생성
◦
프로세스 이미지를 해당 공간에 업로드하고 실행 시작
•
fork() 시스템 콜
◦
별도의 새로운 프로세스 공간을 만들고 fork()를 호출한 부모 프로세스 공간의 데이터를 그대로 복사
◦
자식 프로세스는 pid가 0으로 리턴, 부모 프로세스는 실제 pid 리턴
◦
두 프로세스의 변수 및 PC(Program Count)값은 동일
•
exec() 시스템 콜
◦
별도의 새로운 프로세스 공간을 만들지 않고 exec()를 호출한 부모 프로세스 공간의 TEXT, DATA, BSS 영역을 새로운 프로세스의 이미지로 덮어씌움
execl("실행 파일 경로", "명령서 인자 리스트", NULL); #실행 파일을 직접 지정함
execlp("실행 파일 이름", "명령어 인자 리스트", NULL); #실행 파일을 환경 변수에서 검색함
char *envp[] = {"USER=test", "PATH=/bin", (char *)0};
execle("실행 파일 이름", "명령어 인자 리스트", NULL, envp); #실행 파일을 환경 변수에서 직접 검색하며 환경 변수를 직접 지정함
char *arg[] = {"ls", "-al", NULL};
evecv("실행 파일 경로", arg); #실행 파일을 직접 지정하며 명령어 인자 리스트를 직접 지정함
char *arg[] = {"ls", "-al", NULL};
execvp("실행 파일 이름", arg); #실행 파일을 환경 변수에서 검색하며 명령어 인자 리스트를 직접 지정함
char *envp[] = {"USER=test", "PATH=/bin", (char *)0};
char *arg[] = {"ls", "-al", NULL};
execve("실행 파일 이름", arg, envp); #실행 파일을 환경 변수에서 검색하며 환경 변수와 명령어 인자 리스트를 직접 지정함
Shell
복사
•
wait() 시스템 콜
◦
자식 프로세스와 부모 프로세스의 동기화로 부모 프로세스가 자식 프로세스보다 먼저 죽는 경우를 막기 위해 사용(고아 프로세스)
◦
자식 프로세스가 종료되면 좀비 프로세스가 되어 해당 프로세스 조사를 위한 최소 정보만 가지고 있는 상태가 됨
◦
완전히 끝나면 해당 정보도 삭제되고 부모 프로세스에 SIGCHLD 시그널이 보내짐
•
멀티 프로세스 구현 방식
int main() {
int pid;
int child_pid;
int status;
pid = fork();
switch (pid) {
case -1:
perror("fork is failed\n");
break;
case 0:
execl("/bin/ls", "ls", "-al", NULL);
perror("execl is failed\n");
break;
default:
child_pid = wait(NULL);
printf("ls is complete\n");
printf("Parent PID (%d), Child PID (%d)\n", getpid(), child_pid);
exit(0);
}
}
C
복사
◦
execl()만 사용하면 부모 프로세스가 사라짐
◦
이를 유지하기 위해 fork()로 새로운 프로세스 공간 복사 후 execl() 사용
◦
wait() 함수를 사용해서 부모 프로세스가 자식 프로세스가 끝날 때까지 기다릴 수 있음
•
copy-on-write
◦
copy-on-write란?
▪
fork()를 통해 프로세스 생성 시 4GB의 프로세스 공간을 복사하는데엔 오래 걸림
▪
자식 프로세스 생성 시 부모 프로세스 페이지를 우선 사용
▪
부모 또는 자식 프로세스가 해당 페이지를 읽기가 아닌 쓰기를 할 때 페이지를 복사하고 분리
◦
장점
▪
프로세스 생성 시간을 줄일 수 있음
▪
새로 생성된 프로세스에 새롭게 할당되어야 하는 페이지 수도 최소화
•
exit() 시스템 콜
◦
main 함수의 return 0; 과 exit(0); 의 차이
▪
exit(0) : 즉시 프로세스를 종료 (main() 이후 코드는 실행되지 않음)
▪
return 0 : main() 함수만 종료 (main() 이후 코드가 실행됨)
◦
주요 동작
▪
atexit()에 등록된 함수 실행
▪
열려 있는 모든 입출력 스트림 버퍼 삭제 (stdin, stdout, stderr 파일)
▪
프로세스가 오픈한 파일을 모두 닫음
▪
tmpfile() 함수를 통해 생성한 임시 파일 삭제
◦
atexit()란?
▪
프로세스 종료 시 실행될 함수를 등록하기 위해 사용
▪
등록된 함수를 등록된 역순서대로 실행
프로세스 스케줄링 우선순위 변경
•
nice() 시스템 콜
#include <unistd.h>
int nice (int inc);
C
복사
◦
프로세스 중 사실상 root가 소유한 프로세스만 우선순위를 높일 수 있음
◦
다른 프로세스는 우선순위를 낮출 수만 있음
◦
스케줄링 방식에 따라 우선순위가 적용될 수도 있고 안될 수도 있음
•
getpriority(), setpriority() 시스템 콜
#include <sys/resource.h>
int getpriority(int which, id_t who);
int setpriority(int which, id_t who, int value);
C
복사
◦
which : 프로세스(PRIO_PROCESS), 프로세스 그룹(PRIO_PGRP), 사용자(PRIO_USER) 별로 우선순위를 가져올 수 있음
IPC 기법
•
pipe
◦
기본 파이프는 단방향 통신
◦
fork()로 자식 프로세스를 만들었을 때 부모와 자식간의 통신
•
message queue
◦
msgget() 메서드를 통해 메세지 큐 생성
▪
key : 메세지 큐를 구분하는 유니크한 값
▪
msgflg : 옵션|접근권한
◦
ftok() 메서드를 통해 키 생성
▪
path 경로명의 inode 값과 숫자값(id)를 기반으로 키 생성
▪
경로 삭제 후 재생성 시 inode 값이 달라지므로 다른 키 값이 리턴
◦
msgsnd() 메서드를 통해 메세지 전송
▪
msgflg : 블록모드(0) / 비블록모드(IPC_NOWAIT)
◦
msgrcv() 메서드를 통해 메세지 수신
▪
msgtyp : 0이면 첫번째 메세지, 양수이면 타입이 일치하는 첫번째 메세지
▪
msgflg : 블록모드(0) / 비블록모드(IPC_NOWAIT)
◦
msgctl() 메서드를 통해 메세지 큐를 제어
▪
IPC_RMID : key에 해당하는 메세지 큐 삭제
•
shared memory
◦
커널 영역에 메모리 공간을 만들고 해당 공간을 변수처럼 접근하여 사용
◦
공유 메모리 key를 가지고 여러 프로세스가 접근 가능
◦
shmget() 메서드를 통해 공유 메모리 생성
◦
shmat() 메서드를 통해 공유 메모리 주소 연결
▪
shmaddr : 주소 할당 변수 (보통 (char *) NULL로 사용)
▪
shmflg : 읽기/쓰기(0) / 읽기만(SHM_RDONLY)
◦
shmdt() 메서드를 통해 공유 메모리 해제
▪
shmat()을 통해 공유 메모리 주소를 연결한 변수 전달
◦
공유 메모리 주소를 연결한 변수로 공유 메모리 읽기
◦
공유 메모리 주소를 연결한 변수로 공유 메모리 쓰기
◦
shmctl() 메서드를 통해 공유 메모리 삭제
시그널
•
시그널이란?
◦
UNIX에서 30년 이상 사용된 전통적인 기법
◦
커널 또는 프로세스에서 다른 프로세스에 어떤 이벤트가 발생되었는지를 알려주는 기법
◦
ex) Ctrl+C , Ctrl+Z
•
주요 시그널
◦
SIGKILL : 프로세스를 죽여라
◦
SIGALARM : 알람을 발생한다
◦
SIGSTP : 프로세스를 멈춰라 (Ctrl+Z)
◦
SIGCONT : 멈춰진 프로세스를 실행해라
◦
SIGINT : 프로세스에 인터럽트를 보내서 프로세스를 죽여라 (Ctrl+C)
◦
SIGSEGV : 프로세스가 다른 메모리영역을 침범했다
•
시그널 동작
◦
프로그램에서 특정 시그널의 기본 동작 대신 다른 동작을 하도록 구현 가능
◦
각 프로세스에서 시그널 처리에 대해 다음과 같은 동작 설정 가능
▪
시그널 무시
▪
시그널 블록 (블록을 푸는 순간 해당 프로세스에서 시그널 처리)
▪
프로그램 안에 등록된 시그널 핸들러로 재정의한 특정 동작 수행
▪
등록된 시그널 핸들러가 없다면 커널에서 기본 동작 수행
•
시그널 보내기
•
시그널과 프로세스
◦
PCB에 해당 프로세스가 블록 또는 처리해야하는 시그널 관련 정보 관리
◦
커널 모드에서 사용자 모드 전환 시 시그널 정보 확인해서 해당 처리
스레드
•
Pthread 라이브러리
◦
<pthread.h> 헤더 파일에 정의
◦
모든 함수는 pthread_ 로 시작
◦
크게 두 가지 그룹
▪
스레드 관리 : 생성, 종료, 조인, 디태치 함수 등
▪
동기화 : 뮤텍스 등 동기화 관련 함수
◦
기본 라이브러리 (glibc)와 분리된 libpthread 라이브러리에 구현되어 있으므로 명시적으로 컴파일 필요
▪
gcc -pthread test.c -o test
•
스레드 생성
•
스레드 종료
•
스레드 조인
•
스레드 디태치
◦
해당 스레드가 종료될 경우 즉시 관련 리소스를 해제한다.
•
스레드 동기화