ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 운영체제 03
    쾌락없는 책임 (공부)/운영체제 2021. 4. 10. 16:58
    반응형

    본 포스트는 '신용현'교수님의 운영체제 강의를 듣고

    이해, 정리한 내용들을 올린 포스트입니다.

    - 강의자료는 올리지 않습니다.


    <프로세스들간 협력>

    프로세스들이 서로 협력을 한다는건 파일을 공유하는것이 위주입니다. 이걸 공유함으로서 속도가 빨라지고 분업을 할 수 있어 전체적인 성능 향상을 끌어올릴 수 있습니다.

     예를 들어 A, B프로세스가 있는데 정보 공유를 하지 않는다면 A가 B에게 정보를 보낼 때 커널을 통해서 보내야 합니다. 하지만 메모리의 일부분을 공유한다면 A는 공유된 부분에 변경사항을 전달, B는 그 변경사항을 가져오는 식으로 간편화 할 수 있습니다.

     

    - Producer/Consumer 문제 : 한 프로세스는 정보를 생산하고 한쪽은 소비하는데 이를 어떻게 할것인가?

     * Producer도 다른 곳에서 Consumer이 될 수 있고 Consumer도 다른 곳에서 Producer가 될 수 있습니다.

    * 버퍼에 limit이 없는걸 unbounded, 있는걸 bounded라고 합니다.

     

    1. 메모리 공유로 해결

     - 한정된 버퍼 사이즈

     - in/out을 정해 생산자는 정보를 in에, 소비자는 out에서 소비를 하는 방식    (in/out은 버퍼의 인덱스)

     - 소비 입장에서는 in==out이 된 순간 소비할 수 있는게 없다는 뜻이니 아무것도 하지 않습니다.

     

    2. 메세지 패싱

     - 메모리를 공유하는게 아닌 메세지를 주고(send) 받는(receive)일을 하게 됩니다.

     - 서로 연결을 만들어야 합니다

    2-1. Direct Communication

       - 직접 주고받는 경우

    2-2. Indirect Communication

       - 간접적으로 mailbox를 사용해서 전송하게 됩니다.

       - mailbox가 필요없으면 삭제합니다.

     

    3. 동기화

      - 프로세스들간 동기화를 통해서 정보를 주고받게 됩니다.

    3-1. Blocking

       - 동기적 방식으로 송신자는 메세지 송신을 하고 회답이 있을때 까지 대기합니다.

    3-2. Non-Blocking

       - 비동기 방식으로 알아서 보내고 알아서 받습니다. (독자생존?!)

     

    <쓰레드>

     서버에 많은 사용자들이 몰리게 되면 연산할 항목들이 점점 많아지게 됩니다. 특히 웹 서버의 경우 입출력할 일이 정말 많은데 이 입출력을 하는동안 다른 일을 할 수 있습니다(CPU입장에서는 시간이 많이 남은것). 그런데 다른 일을 하기 위해 프로세스를 생성하는건 시간, 자원이 너무 많이 소모됩니다. 그래서 프로세스를 대신해 상대적으로 가벼운 쓰레드를 생성해서 여러 일을 처리할 수 있게 해주는 것입니다.

     

    쓰레드는

     - 프로세스보다 가볍고 오버헤드가 적습니다 (아예 없는게 아닙니다)

     - 프로세스 하나에 여러 쓰레드가 생성됩니다.

     - 코드와 데이터, 열어둔 파일, signal handler, 여러 환경 요소(현재 디렉토리, 유저 아이디 같은것들)는 공유합니다.

     - 레지스터 값이나 스택, 쓰레드 ID는 공유하지 않습니다.

    프로세스  > 쓰레드 생성 > 쓰레드
    Data X
    Code X
    Stack Stack

     

    쓰레드와 프로세스 비교

     쓰레드 하나가 작동하지 않으면 다른 쓰레드가 하면 됩니다. 프로세스가 멈추면 (다른 프로세스가 없을시)다른 일을 할 수 없게 됩니다. 따라서 쓰레드가 많은게 응답성이 더 좋다고 할 수 있습니다. 

     

     

    유저 쓰레드와 커널 쓰레드

    - 유저 쓰레드 : 쓰레드를 라이브러리에서 구현한 것.      (윈도우)

    - 커널 쓰레드 : 운영체제 차원에서 만든 것.     (리눅스)

     

    + 리눅스에서 쓰레드

      : clone이란 시스템 콜로 쓰레드를 만들게 됩니다. 그리고 쓰레드와 프로세스를 직접적으로 구분하지 않고 공유하는 정도에 따라 '쓰레드에 가깝다', '프로세스에 가깝다' 라고 합니다.

     (뭘 공유해야 더 쓰레드같고 더 프로세스같은지는 위 항목과 같습니다)

     

     

    <멀티 코어>

     코어가 여러개가 되면 '병렬성'이 좋아진다고 합니다. 병렬성이 좋아지는건 time slice를 잘 하는게 아니라 실제로 같은 시간에 여러 일을 하는걸 의미합니다. 이런 멀티코에서는 일, 자원 등을 분배하는데 있어 고려할게 많습니다.

     *고려할 것들 : 일은 어떻게 나누나(프로세스별/쓰레드별), 일을 나눈 뒤 밸런스는? 데이터는 어떻게 나누는가? 데이터간 의존도는? 

     

    + Concurrency / Parallelism

     : 전자는 동시에 수행하는 것처럼 일하는거고 후자는 실제로 동시에 수행하는걸 의미합니다.

     

     

     

    <CPU 관리하기>

     

    CPU에게 IO란

    - CPU에게 입출력은 많은 메모리를 잡아먹게 됩니다. 그래서 입출력 과정에서는 연산 속도를 높여서 CPU를 많이 점유하게 됩니다. 

    - 입출력 되에도 각 프로세스마다 걸리는 시간이 달라 스케쥴링이 중요하게 작용하게 됩니다.

     

     

    CPU Scheduler - 스케쥴러

    - Ready 큐에는 현재 대기 상태의 프로세스들이 많이 있으며 스케쥴러가 이 중 하나를 고르게 됩니다.

    - 언제 다음 프로세스를 고르게 되나

    ([실행] - Running, [대기] - Waiting, [준비] - Ready)

    Preemptive 프로세스가 [실행]에서 [준비]로 바뀔 때
    프로세스가 [대기] 상태에서 [준비] 상태로 바뀌게 될 때 (입출력 프로세스)
    Non-Preemptive 프로세스가 [실행]에서 [대기]로 바뀔 때
    CPU에서 프로세스가 나갈 때

    위 표에서 Preemptive는 OS가 직접 수행을 중단하는 것을 의미하고 non은 프로세스 스스로가 종료하는걸 의미한다.

    특히 파란 글씨로 되어 있는 부분을 하는 작업은 입출력밖에 없으며 데이터의 주소를 찾는 동안 CPU를 멈출 순 없으니 다른 일을 찾으러 가는 것입니다.

     

     

    <Dispatcher>

     

     

    <어떤 스케쥴러가 좋은 것인가?>

    알고리즘 항목 좋은 알고리즘
    CPU 이용도 - CPU를 얼마나 많이 사용하는가 높을수록
    Throughput(수율) 높을수록
    Turnaround Time - 완료까지 걸리는 시간 낮을수록
    Waiting Time - Ready큐에서 기다리는 시간 낮을수록
    Response Time - 응답까지 걸리는 시간 낮을수록

    여기서 응답까지 걸리는 시간에서 '응답'이란 Ready큐에서 빠져나와 실행된다는걸 응답이라고 보면 되겠습니다.

     

    물론 지금까지 아주 쩌는 CPU는 없기 때문에 스케쥴러는 위 항목에서 적절한 편차를 찾아야 합니다.

     

    <CPU 스케쥴러 알고리즘 종류>

    1. FCFS (처음 온놈이 바로 예약되는 것)

     간단하게 이야기하면 선착순으로 각 프로세스 특성과 관계 없이 먼저 오는 프로세스를 먼저 실행한다고 보면 됩니다. 들어오는 프로세스의 순서에 따라 Waiting Time 평균이 달라지며 먼저 들어온 프로세스가 먼저 진행되니 non-Preemptive라고 할 수 있습니다. 

     

    2. SJF (짧은 일 먼저)

     빨리 수행할 수 있는 일 먼저 하게 되며 놀랍게도 Preemptive, non-Preemptive2가지 모드가 있습니다.

    Preemptive 모드의 경우 각 프로세스들의 도착 시간을 생각해야 되서 조금 더 복잡하지만 Waiting Time을 평균적으로 줄여줍니다.

    - 모두의 대기시간이 중요한 상호작용이 많은 프로그램의 경우 이 방법을 사용하는게 좋습니다.

    - 짧은 일이라는걸 어떻게 아는가?

      프로세스의 길이는 이전 프로세스의 '예상 수행시간'과 '실제 수행시간'을 기반으로 예측을 하게 됩니다. 정확한 값이 있는건 아니죠.

     

    (N번째의 CPU 사용 예측치) = (적응속도) * (N-1 프로세스의 실제 시간) + (1 - 적응속도) * (N-1 프로세스 예측 시간)

     

     위의 수식을 이용해서 다음에 오는 프로세스는 '이정도 시간을 가질 것이다'를 예측하게 되며 [적응속도]는 0~1의 값으로 0에 가까울수록 이전의 예측에 조금 더 가중치를 주겠다는 것입니다.

     

    3. 우선순위 스케쥴링

     말 그대로 각 프로세스에 우선순위를 부여한다는 이야기로 우선순위가 높을수록(값이 작을수록) 우선 할당을 해준다는 것입니다. SJF의 경우 빨리 수행이 가능한 프로세스에 우선순위를 주게 되니 우선순위 스케쥴링의 하위 버전이라고 보면 됩니다.

     

     한가지 문제점은 우선순위가 낮게 잡히게 되면 다른 프로세스가 계속 들어와 '평생 수행할 수 없는'상태가 될 수 있는데 이는 Aging이란 기법을 넣어 시간이 흐를수록 우선순위를 높여준다는 기법입니다. 이를 통해서 평생 수행할 수 없는 상태에서 벗어날 수 있게 해줍니다.

     

    4. Round Robin

     평소 제가 CPU 사용하는 방식이라고 이해한 것입니다. 그냥 일정 시간을 정해두고 이 시간이 시나면 프로세스 완료여부와 관계없이 무조건 Ready큐로 보내고 다른 프로세스를 불러오는 것입니다. 여기서 N개의 프로세스가 있고 시간의 단위가 q라고 하면

    (N-1)q

     보다 더 기다리는 일은 없습니다.

     

     여기서 중요한 점은 단위 시간이 크게 되면 FCFS와 다를바 없어지게 되고 너무 짧으면 주소값이 너무 방대해져 오버헤드가 증가하게 됩니다. 따라서 시간 단위를 적절히 조절하는게 좋습니다.

     

    * SJF보다 Turnaround Time은 증가하게 되지만 Response Time은 아주 짧습니다.

    반응형

    '쾌락없는 책임 (공부) > 운영체제' 카테고리의 다른 글

    운영체제 06  (0) 2021.05.27
    운영체제 05  (0) 2021.05.19
    운영체제 04  (0) 2021.05.19
    운영체제 02  (0) 2021.04.10
    운영체제 01  (0) 2021.04.09

    댓글

Designed by Tistory.