Search

[시스템 프로그래밍] 컴퓨터 공학 전공 필수 올인원 패키지

강의

Loading PDF…

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
스레드 생성
스레드 종료
스레드 조인
스레드 디태치
해당 스레드가 종료될 경우 즉시 관련 리소스를 해제한다.
스레드 동기화