시스템 프로그래밍
운영체제, 하드웨어와의 상호작용을 프로그래밍 하는 것
커널이 제공하는 기능을 직접 제공받으며 low-level에서 동작하는 프로그램을 작성하는 것
* 커널이 제공하는 기능 -> 시스템 콜 주로 활용
파일 디스크립터
프로세스는 운영체제로부터 파일을 할당받는데,
파일을 식별하기 위해 운영체제로부터 할당받는 정보가 파일 디스크립터
- 입출력장치, 파이프, 소켓도 파일 디스크립터로 식별
일반적으로 0 이상의 정수 형태
프로세스가 파일을 열거나 생성할 때 운영체제는 해당 파일에 대한 파일 디스크립터 할당
저수준에서 파일을 식별하는 정보
※ 고정된 파일 디스크립터 값(표준 입출력)
- 0번 : 표준 입력 (키보드)
- 1번: 표준 출력 (모니터)
- 2번: 표준 에러
파일 포인터
파일을 스트림처럼 읽고 쓰기 위한 자료형 -> 편리한 함수 기능 많음
파일 디스크립터가 저수준에서 파일 식별하는 정보라면 파일 포인터는 고수준 파일 식별 정보
하드링크와 심볼릭링크
아이노드
파일 이름을 제외한 모든 것을 가리키고 있는 색인 블록
아이노드를 사용하는 이유
외부 단편화
작업보다 많은 공간이 남아 있더라도 실제로 그 작업을 받아 들이지 못하는 경우
ex)연속적으로 파일을 a,b,c,d,e으로 할당되있고 프로세스가 끝나서 a,b,c인 파일(크기가 3)이 삭제 된 후 a,b,c,d에 새로운 파일(크기가 4)을 할당할 수 가 없어진다.
아이노드 조회
ls -i, stat
아이노드 사용량이 100퍼로 찼을 경우 저장장치에 용량이 남아있어도 파일 생성 불가
하드링크
하드링크 생성시 같은 아이노드를 공유하는 하드 링크 파일이 생성됨
하드 링크 파일은 원본 파일과 같은 데이터 공유
원본 파일이 삭제/이동해도 하드 링크 파일은 남아있음
여러 이름으로 파일을 참조하고 싶을 때 사용
하드링크 생성하기(리눅스)
ln [원본파일이름] [하드링크파일이름]
심볼릭링크
심볼릭링크 파일(소프트링크, ex) 윈도우의 바로가기)
심볼릭링크 생성시 원본 파일을 가리키는 새로운 아이노드를 만든다
원본 파일과 같은 데이터를 공유하지 않음(원본 파일의 위치만 알 뿐)
원본 파일이 삭제/이동하면 심볼릭 링크 파일은 사용 불가
하드 링크 파일에 비해 조작이 간편
복잡한 경로에 있는 파일을 참조하고자 할 때 사용
심볼릭 링크 생성하기(리눅스)
ln -s [원본파일이름] [심볼릭링크파일이름]
파일 속성 다루기
파일 속성
파일
보조기억장치의 의미있는 정보의 집합
구성요소
이름, 실행하기 위한 정보, 부가 정보
stat -c %명령어
%명령어에 따라 stat 정보에서 원하는 것을 뽑아낼 수 있음
파일(+디렉터리) 접근 단위: 블록
섹터 단위로 접근하지 않음
파일 메모리 매핑
프로세스 메모리 영역에 파일의 내용 일부에 대응시키는 것
디스크에 있는 파일에 읽고 쓰는 것(파일 입출력)이 아니라 프로세스 메모리 영역에 읽고 쓰기
-> lseek의 번거로움 감소, 불필요한 시스템 콜 호출 횟수 감소
두 개 이상의 프로세스가 같은 영역을 매핑할 경우 다른 프로세스와의 통신 가능
매핑은 페이지 단위(페이지 배수)로 이루어짐
프로세스 다루기
프로세스란 실행 중인 프로그램 -> 같은 프로그램이라도 별도의 프로세스일 수 도 있음
포그라운드 프로세스, 백그라운드 프로세스
프로세스 제어 블록(PCB)
PID(PPID), 레지스터, 스케줄링 정보, 메모리 정보, 사용한 파일 정보, 입출력장치 정보
대표적인 프로세스 상태
생성
준비 W
실행 R
대기 S
종료 S
Z: Zombie: 프로세스 종료 후 자원이 반환되었지만 커널 영역에 프로세스가 남아있는 상태
프로세스는 계층적 구조로 되어있음
fork: 복사본 만들기 -> 부모 프로세스가 자기 복제본으로 자식 프로세스를 만듦
exec: 새로운 코드로 대체(덮어쓰기)
스레드 다루기
스레드
프로세스를 구성하는 실행 흐름의 단위
각기 다른 스레드 ID, 프로그램 카운터, 레지스터, 스택
프로세스 간에는 기본적으로 자원을 공유하지 않음
스레드 간에는 프로세스의 자원을 공유
프로세스 간에도 자원 공유가 가능하다 -> 프로세스간 통신 IPC
공유 메모리를 통한 통신, 파이프를 통한 통신, 네트워크 소켓을 통한 통신 등
공유 메모리 기반 IPC
공유 메모리
다수의 프로세스가 공유 가능한 메모리 영역
공유하는 메모리를 읽고 씀으로써 프로세스간 통신이 가능
파이프 기반 IPC
pipe란
단반향 IPC 도구
한 쪽에서는 파이프를 읽고, 한 쪽에서는 파이프에 쓴다
주로 Stream 형태의 데이터를 주고받을 때 사용
파이프는 일종의 파일: file descriptor를 기반으로 읽고 쓰기 수행
파이프에 더이상 쓸 공간이 없을 때 쓰면 block
파이프가 비어 있을 때 읽기를 시도하면 block
지나치게 큰 값(리눅스의 경우 4KB 이상) 쓰기 지양
양방향 통신 시 필요하지 않는 디스크립터는 닫아줘야한다. ex)부모에서 자식으로 갈 때는 부모의 읽기와 자식의 쓰기 디스크립터를 닫고 자식에서 부모로 갈 때는 부모의 쓰기와 자식의 읽기 디스크립터를 닫아준다.
시그널
시그널이란
소프트웨어 인터럽트
프로세스에게 특정 이벤트가 발생했음을 알리는 수단
다양한 시그널이 있고, 시그널 종류별로 번호가 할당되어 있다
대표적인 시그널
SIGCHLD: child stopped or terminated
SIGILL: illegal instruction
SIGINT : interrupt from keyboard (ctrl+c)
SIGKILL: kill signal (처리 불가능)
SIGSEGV: invalid memory reference
SIGTERM: termination signal (처리가능)
SIGUSR1: user-defined signal 1
SIGCONT: continue if stopped
SIGSTOP: stop process(처리 불가능)
시그널마다 기본 동작이 정해져 있고, 처리가 가능한 것들이 있다
소켓 프로그래밍
소켓
네트워크를 경유하는 프로세스 간 통신의 종착점
소켓의 구성 요소
TCP + IP 혹은 UDP + IP
출발지 IP 주소
출발지 포트 번호
목적지 IP 주소
목적지 포트 번호
소켓은 특별한 형태의 파일이라 볼 수 있다
파일 열기, 닫기, 쓰기, 읽기
소켓 열기, 닫기, 송신하기, 수신하기
소켓은 프로세스 간 통신 기법(IPC)의 일종이다
수신 프로세스 & 송신 프로세스
TCP 소켓, UDP 소켓
TCP -> 연결 지향형
UDP -> 비연결지향형