6 minute read

1. 정의

컴퓨터 하드웨어와 소프트웨어 자원을 관리하고 컴퓨터 프로그램들에 서비스를 제공하는 시스템 소프트웨어이다. 운영체제를 통해 사용자는 컴퓨터 시스템을 편리하게 사용할수 있으며, 하드웨어를 효율적인 방법으로 사용할수 있다. 운영체제는 커널, 시스템 프로그램, 응용 프로그램으로 구성되어있는 패키지로 간주할수 있다.

성능을 나타내는 4가지 요소는 Throughput (단위시간당 처리능력), Turnaround Time(반환 시간), Reliability (신뢰도), Availability (신뢰 가능도)가 있다.

2. 리눅스의 부팅과정

1. BIOS (Basic input output system)

시스템의 무결성 여부를 확인한후 MBR에 있는 부트로더 프로그램을 찾아서 메모리에 로드하고 실행후 권한을 위임한다 부트로더 프로그램은 여러 디바이스에 있을수 있고 BIOS에 정의된 우선순위를 참고하여 탐색한다. MBR은 Master Boot Record의 약자로 부팅가능한 디스크의 첫번째에 위치해있다. (Typically /dev/hda, or /dev/sda) 512 바이트 이하의 크기를 가지고 있으며, boot loader(GRUB나 LILO, 파티션 테이블정보, 패리티 비트로 구성되어있다.

2. GRUB (Grand Unified Bootloader)

GRUB은 Grand Unified Bootloader의 약자로 여러개의 커널 이미지가 있다면 선택할수 있는 screen이 뜬다. GRUB 은 LILO와 달리 파일시스템에 대한 정보를 가지고 있다. 설정파일은 /boot/grub/grub.conf 에 저장되며 각각의 이미지들에 대한 kernel과 initrd image (실제 루트 파일 시스템을 사용할 수있게 되기 전에 마운트되는 초기 루트 파일 시스템)의 경로가 저장되어있다. GRUB은 최종적으로 kernel과 initrd image를 메모리에 적재하고 실행하여 제어권을 넘긴다

initrd는 Initial RAM Disk의 약자이다. initrd는 커널에의해 real 루트 파일시스템이 마운트 되기 이전에 임시 루트 파일 시스템으로 이용되며 필수적인 컴파일된 드라이버들을 포함하고 있다. (하드디스크나 기타 다른 하드웨어장비에 접근하기 위한 드라이버들)

3. Kernel

루트 파일 시스템을 읽기 전용으로 마운트 한후 swapper 프로세스(PID 0번)을 호출한다. swapper는 커널이 사용할 각 장치드라이브를 초기화하고 /sbin/init 을 실행한다. init 프로그램은 the process id (PID) of 1을 부여 받는다. ps -ef grep init을 통해 확인할수 있다.

4. init

init 프로세스는 모든 프로세스의 조상 역활을 하며 각종 서비스를 제공하는 다른 프로세스를 동작시키는 역활을 한다. init 프로세스는 런레벨(0 ~ 6)이라는 개념을 가지고 있다.최근에는 더다앙햔 기능을 가진(CGroup 제어) systemd로 거의 바뀌어 가는 추세이다. 해당하는 런레벨에 맞는 스크립트 /etc/rc.d/rc#.d/* 를 실행한후 로그인프롬포트를 실행한다.

3. tty

TTY(teletypewriter)란 컴퓨터를 운용하기 위한 목적으로 텍스트를 사용자와 컴퓨터가 주고 받는 인터페이스이다. 모니터, 키보드로 직접 연결된 콘솔모드(tty0, tty1, tty2) , 네트워크로 통해 연결된 터미널 모드(pts/n) 가 있다. x-window도 터미널모드의 일종이다.

4. X WINDOW

X WINDOW는 플랫폼 독립적인 GUI 개발 프로젝트이다. X WINDOW는 윈도우OS와 다르게 클라이언트 서버 모델에 기반한 사용자 인터페이스이다. X WINDOW에서의 서버와 클라이언트의 메시지 교환을 위해 X 프로토콜을 사용한다.

5. 인터럽트

히던일을 멈추고 정해진 주소의 데이터를 옮기고 서비스 루틴을 수행하는 행위를 인터럽트라고 부른다. 시분할 시스템에서 프로세스들의 기아현상을 막기 위해 주기적으로 인터럽트가 발생한다.

6. DMA

고속의 입출력장치에 사용하는 기법. 한번의 인터럽트에 많은 양의 데이터를 CPU가 아니라 장치제어기가 직접 전송한다. 이를 통해 CPU가 동시에 다른작업을 수행할수 있도록 해준다.

7. 멀티 프로세서와 멀티 코어 프로세서

멀티 프로세서는 쉽게 설명하면 여러개의 CPU로 구성하는 기법을 의미하고 멀티 코어인 경우 하나의 칩에 여러개의 CPU 코어를 포함시키는구조이다. 멀티 코어 프로세서의 경우 데이터베이스나 웹서버 같은 동일유사한 작업을 동시에 많이 처리하는 서버 시스템 구조에 적합하다.

8. 모드의 구분

사용자 프로그램이 동작하는 모드와 운영체제가 동작하는 모드를 구분한다. 몇몇 명령어는 커널모드에서만 실행되도록 특권을 가지고 있으며, 시스템 콜이 필요한 상황에서는 커널모드로 전환되었다가 다시 사용자모드로 복귀한다.

9. 시스템 콜

운영체제가 지원하는 서비스에 대한 프로그래밍 인터페이스. 프로세스 제어, 파일 조작, 장치관리, 정보유지, 통신, 보호 기능이 필요할때 시스템 콜을 사용한다.

10. 프로세스

메모리에 적재된 실행중인 프로그램을 의미한다. 프로세스는 프로그램 카운터의 값과 프로세스 레지스터의 내용으로 결정된다. stack, data section, heap, text section으로 메모리에 로딩된다. fork()를 통해 새로운 프로세스를 만든후 exec()으로 프로세스 메모리 공간을 새로운 프로그램으로 대체한다.

11. IPC

커널영역에서 프로세스간의 메시지의 수송신을 통해 통신을 하는 기법을 의미한다. 파이프, 메시지 큐, 공유 메모리, 메모리 맵, 소캣 기법이 있다.

파이프는 프로세스간의 단방향 통신을 하기 위한 기법으로 생성된 파이프에 대해서 Write 또는 Read만 가능하며 양방향 통신을 위해서는 파이프가 2개 필요하다. 파이프로 통신할때 읽기와 쓰기 작업이 동시에 진행될수 없다. Named 파이프든 파이프에 이름을 지정하여 서로 연관이 없는 프로세스들이 이름을 가진 파이프를 통해 통신할수 있다.

메시지 큐는 파이프가 stream 파일을 통해 통신을 하는것과 다르게 메모리 공간에서 구조체를 이용하여 여러개의 프로세스가 선입선출 형태로 통신할수 있다.

공유메모리는 사용자가 지정한 크기의 메모리를 프로세스간에 공유하는 구조이다. 프로세스간 read, write을 양방향으로 진행할수 있다.

소켓은 서버와 클라이언트사이의 IP주소, 프로토콜, 포트의 연결할때 양끝점으로 정의된다. 소캣은 클라이언트 서버 구조로 스트림 파일을 사용하여 다른 시스템 간의 양방향 통신시에 많이 사용되는 기법이다.

RPC는 네트워크로 연결된 시스템 사이에서 다른 시스템에 있는 프로시저 호출기법이다. 클라이언트에서 메시지를 구성하여 RPC로 호출하면 서버에서 해석하여 프로시저를 실행후 결과를 반환한다. 네트워크 통신을 위한 작업에 신경쓰지 않고 원격지의 자원을 사용할수 있는것이 장점이며 java에서는 원격 메소드 호출이라는 기법을 사용한다.

12. 스레드

프로세스 내의 작업을 의미한다. 만약 하나의 프로세스 내에 여러 제어로 구성되어있다면 이를 다중 스레드 프로세스라고 부른다. 스레드는 코드영역, 데이터영역, 운영체제 자원을 공유한다. (스택과 레지스터는 스레드마다 사용) 다중 스레드 프로그래밍은 다중 코어를 더효율적으로 사용할수 있고 병행성을 더 향상시킬수 있다. 스레드 라이브러리를 통해 프로그래머가 스레드를 생성하고 관리할수 있다.

13. POSIX

다른 운영체제들 사이의 호환성을 위해 만든 System interface, shell, utilite가 포함된 IEEE 표준이다. System interface에는 thread 생성을 위한 표준 API도 포함되어있다.

14. 멀티프로세싱, 멀티스레딩

fork(), exec()을 활용하여 여러개의 프로세스로 나누어 하나의 job을 달성하는 행위. context switching 부하가 큰 단점이있다. 반면 멀티스레드의 경우에는 하나의 job을 달성하기 위해서 여러개의 스레드를 사용하는 행위를 의미한다. 스레드의 경우 code, data, heap영역을 공유하기 때문에 context switching 비용이 적다. (PCB는 여러개의 TCB블록을 가지고 있는데 TCB블록의 크기가 현저히 작다)

15. 비선점 스케줄링

일단 프로세스에 자원이 할당되면 job이 끝날때까지 다른 프로세스가 자원을 빼앗을수 없는 방식이다. 어느정도 응답시간을 예측할수 있는 임베디드 시스템에서 많이 사용될것으로 추측된다.

FCFS는 CPU를 먼저 요청한 프로세스가 CPU를 먼저 할당 받는 비선점 방식이다. 따라서 CPU를 놓을때까지 점유하므로 시분할 시스템에서 문제가 된다.

SJF는 가장 짧을것으로 추정되는 CPU버스트를 가진 프로세스에 CPU를 할당한다. 선점 비선점 둘다가능한데, 선점 방식의 경우 더 짧은 시간의 프로세스가 있다면 CPU를 내어준다.

우선순위 스케줄링은 가장 높은 우선순위를 가지는 프로세스에게 할당하는 기법으로 선점 비선점 둘다 운용가능 하다.

16. 선점 스케줄링

비선점 스케줄링과 다르게 정해진룰에 의해 다른 프로세스의 job이 끝나지 않더라고 자원을 빼앗아 다른 프로세스에 할당하는 스케줄링 기법이다. 기아의 가능성을 줄여준다.

라운드 로빈 스케줄링 선점 스케줄링의 일종으로 퀀텀 단위로 시간을 쪼개어 프로세스들에게 자원을 할당하는 기법이다.

다단계 큐 스케줄링 각 큐별로 다른 스케줄링 라고리즘을 적용하는것이 가능하다.

17. 동기화

프로세스들이 자원을 공유하고 있다면 race condition이 유발될수 있다. 따라서 이를 막기위해 프로세스 들중 오직 하나만 임계영역에 진입하기 하고(상호배제), 임계영역상에 프로세스가 없으면 다른 프로세스가 진입하도록 유도하고, 무한하게 대기하지 않도록 막아야한다.

페터슨의 해결책은 임계영역에서 두개의 프로세스가 두개의 변수를 공유하여 임계영역문제를 해결하는것이다. 하나는 프로세스가 임계영역에 진입할 준비를 확인하는 배열이고, 하나는 프로세스가 실행될수 있는지를 확인하는 변수를 공유한다.

# 프로세스 i의 관점에서 서술된 코드
do{
  flag[i] = TRUE;
  turn = j;
  while (flag[j] && turn == j);

    --- critical section ---

  flag[i] = FALSE;
  --- remainder section ---

} while(TRUE);

프로세스 i가 임계영역에 진입하기 위해서는 flag[j]가 false이거나 turn값이 i 이어야하므로 상호배제, 진행, 무한대기가 발생하지 않는 상태가 되므로 올바른 알고리즘이라 볼수 있다.

18. 뮤텍스, 세마포어

뮤텍스는 쓰레드나 프로세스에 의해 공유될수 있는 key를 기반으로 하는 상호베제 기법이고 세마포어는 현재 자원에 접근할수 있는 쓰레드, 프로세스의 수를 나타내는 값을 통해 상호베제를 구현하는 기법이다.

세마포어는 뮤텍스와 다르게 세마포어의 변수만큼 프로세스나 스레드가 접근할수 있지만 뮤텍스는 오직 1개만 가능하다. (그래서 이진 세마포어의 경우 뮤텍스와 비슷한 양상을 가지고 있다.) 따라서 락을 해제할때도 세마포어의 경우 다른프로세스나 쓰레드가 해제할수 있지만 뮤텍스는 오직 락을 가진 프로세스/쓰레드만이 해제할수 있다.

19. 교착상태

교착상태를 나타내는 대표적인 비유는 ‘철학자들의 만찬’ 이 있다. 철학자 4명이 있는데 음식이 4개고 포크가 4개인 상황에서 음식을 먹을려하는경우 포크가 2개가 필요하다. 이때 철학자 모두 포크를 1개씩 집으면 음식을 먹을수 없는 상황이 발생한다.

상호배제, 프로세스 하나가 자원을 점유하고 다른 프로세스들은 대기중일때 (정지대기), 비선점, 순환대기 상황이 모두발생하면 교착상태가 발생할수 있다.

교착상태는 예방, 회피, 복구를 통해 대응한다. 예방은 4가지 상황중 하나라도 발생하는 상황을 막는것이지만 성능저하를 일으킬수 있다. 회피는 교착상태를 미리 예측하여 자원을 할당하지 않는것으로 대표적으로 뱅커 알고리즘을 통해 자원을 요청할때 마다 예측을 진행한다. 만약 데드락을 예방, 회피하지 못했을때는 복구를 진행하게 된다. 이때 정해놓은 기준에 따라 어떤 프로세스를 킬할지 판단한다.

20. 참고자료

https://parksb.github.io/article/12.html

https://jhnyang.tistory.com/notice/31

Leave a comment