Ch.3 Processes

imagine·2025년 3월 13일

OS

목록 보기
4/6

Process Concept

  • Process (프로그램 실행)

    • process는 순차적으로 진행되어야 한다

    • 현재 활동 상태는 program counter 값과 register의 내용으로 표시된다

    • 프로그램 실행은 GUI 마우스 클릭, 명령줄 입력 등을 통해 시작한다

    • 하나의 프로그램은 여러 실행을 할 수 있다. (ex. chrome)

    • 프로세스의 메모리 배치

      • text section: 실행 코드
      • data section: 전역 변수
        • 초기화된 데이터
        • 초기화되지 않은 데이터
      • heap section: 프로그램 실행 중에 동적으로 할당되는 메모리
      • stack section: 함수 호출할때 임시 데이터 저장소(매개변수, 반환주소, local 변수)

text, data 영역의 크기는 고정되기 때문에 프로그램 실행시간 동안 크기가 변하지 않는다.

그러나 stack, heap 영역의 크기는 가변적인데, 함수가 호출될 때마다 활성화 기록이 stack에 push되며, 함수에서 제어가 되돌아오면 pop된다.

⇒ stack, heap 구역이 서로의 방향으로 커지더라도 운영체제는 서로 겹치지 않도록 해야한다.

Process State

프로세스는 실행되면서 그 상태가 변한다.

  • new: 프로세스가 생성되고 있다
  • running: 명령어가 실행되고 있다 → only one!
  • waiting: 프로세스가 어떤 이벤트가 일어나기를 기다린다 (e.g. I/O완료 또는 신호의 수신)
  • ready: 프로세스가 processor에 할당되기를 기다린다 ⇒ setup system
  • terminated: 프로세스의 실행이 종료된다

다른 실행에 의해 interrupt → ready로 이동

I/O 입력 기다릴때 → waiting으로 이동

Process Control Block (PCB)

각 프로세스와 관련된 정보들을 표현한 블록 (task control block이라고도 불린다.)

              <PCB>
  • Process state: running, waiting, etc..
  • Program Counter: 다음 실행할 명령어의 주소를 가르킨다.
  • CPU registers: 여러 레지스터와 상태 코드 정보를 포함하는데, 이들은 나중에 프로세스가 다시 스케쥴 될 때 계속 올바르게 실행되도록 하기 위해서 인터럽트 발생 시 저장되어야 한다.
  • CPU-scheduling information: 프로세스 우선순위, 스케쥴 큐에 대한 포인터 등을 포함한다.
  • Memory-management information: 운영체제에 의해 사용되는 메모리 시스템에 따라 기준(base)레지스터, 한계(limit)레지스터의 값, 페이지 테이블, 세그먼트 테이블 등과 같은 정보를 포함한다.
  • Accounting information: CPU 사용시간과 경과 시간, 시간제한, 계정 정보, 프로세스 번호 등을 포함한다.
  • I/O status information: 프로세스에 할당된 입출력 장치, 열린 파일 목록 등을 포함한다.

Process Representation in Linux

Represented by the C structure taks_struct

Threads

프로그램이 여러 개의 실행 task를 갖게 하는 방법

  • 대부분의 현대 운영 체제는 한 프로세스가 다수의 실행 스레드를 가질 수 있도록 허용한다.
  • 여러 스레드가 병렬로 실행될 수 있다는 것을 의미한다

Process Scheduling

CPU에서 실행할 process를 선택하는 것

scheduling의 목적은 CPU 활용을 극대화 하는 것과 사용자가 각각 program과 상호작용할 수 있게 하는 것이다.

  • 각 processor에서 동시에 하나의 process만이 실행할 수 있다
  • process scheduler는 이용가능한 process들 사이에서 선택한다
  • 나머지 process들은 scheduling queue에서 기다린다
    • scheduling queue : process 대기 목록
    • Degree of multiprogramming : 현재 메모리에 있는 process 수

Scheduling Queues

Ready queue: 주 메모리에 있는 모든 프로세스의 집합이다. 프로세스가 시스템에 들어가면 ready queue에 들어가서 준비 상태가 되어 CPU 코어에서 실행되기를 기다린다.

Wait queue: 특정 이벤트가 발생하기를 기다리는 프로세스 집합(I/O 요청 완료 같은)

Scheduling Queues

process scheduling의 표현

Context Switch

CPU가 한 프로세스에서 다른 프로세스로 전환한다

  • CPU가 다른 프로세스로 전환되면서, 현재 프로세스의 상태를 저장하고 저장된 상태를 새로운 프로세스에 로드한다.

Multitasking in Mobile Systems

최근 모바일 시스템은 사용자 어플리케이션을 위한 멀티태스킹을 제공한다.

  • Foreground : 현재 열려있고 화면에 나타나는 application
  • Background : 메모리에 남아 실행되지만, 화면에 나타나지 않음

안드로이드는 foreground와 background를 실행한다

  • 백그라운드 프로세스는 서비스를 사용하여 task를 수행한다
    • 백그라운드 프로세스가 중단되더라도 서비스가 계속 실행될 수 있다
    • 서비스는 UI가 없고, 메모리 사용량이 적다.
  • 분할 화면

Operations on Processes

Process Creation 1

부모 프로세서는 자식 프로세서를 생성하고, 이는 차례대로 다른 프로세서들을 생성하여 프로세스 트리(tree of process)를 형성한다.

process identifier(pid)를 통해 프로세스를 식별하고 관리한다.

  • pid는 독특한 값을 각각의 프로세스에 제공한다
  • index로 사용될 수 있다

option

  • Resource sharing options

    • 부모와 자식은 모든 리소스를 공유한다.
    • 자식은 부모 리소스의 부분집합을 공유한다.
    • 부모와 자식은 리소스를 공유하지 않는다.
  • Execution options

    • 부모와 자식은 동시에 실행된다
    • 부모는 자식이 끝날 때까지 기다린다
  • Address space

    • 자식 프로세스는 부모 프로세스의 복제품이다
    • 자식은 로드된 새 프로그램을 가진다

Displaying Process Information

  • Linux
    • $ ps [-ef]
  • window
    • 작업관리자
    • 프로세스 익스플로러 (process explorer)

Process Creation 2

fork()로 복사본을 만든 다음 execlp()로 복사본의 내용을 새로 덮어씌워서 새로운 프로그램을 만든다

in Linux

  • fork() 새로운 프로세스를 형성한다.
    • 부모 프로세스 return → pid of child
    • 자식 프로세스 return → 0
  • exec() 프로그램 실행
    • 새 프로그램이 기존의 프로그램을 대체한다
  • wait() 자식 프로세스가 끝날 때까지 기다린다.

A Tree of Processes in Linux

프로세스 트리 in 리눅스

Example of Process Creation

More About fork()

#include <unistd.h>
pid_t **fork**(void);

자식 프로세스 생성

calling 프로세스(부모 프로세스)를 복제해서 새 프로세스(자식 프로세스) 생성

자식과 부모 프로세스는 분리된 메모리 공간에서 실행한다

fork()를 하는 시점에 두 메모리 공간은 같은 내용을 갖는다

메모리 작성, 파일 mapping, unmapping는 다른 프로세스에 영향을 주지 않는다

리턴 값 : child 성공 : 0

    parent 성공 : child PID

error : -1

자식 프로세스의 리소스

  • 데이터(변수) : 부모 프로세스의 변수를 복사함
    • 자식 프로세스는 자신의 주소 공간을 갖는다
    • 유일한 차이점은 child의 pid가 fork()로부터 리턴된다는 것이다.
  • 파일 : opened before fork() : 부모와 공유
                 //        after     //    : 공유하지 않음

Process Termination

프로세스가 마지막 명령문의 실행을 끝내고, **exit()** 시스템 콜을 사용하여 운영체제에 자신의 삭제를 요청하면 종료한다.

  • 이 시점에서 프로세스는 자신을 기다리고 있는 부모 프로세스에 상태 값을 반환할 수 있다
  • 프로세스의 리소스는 운영 체제에 의해 할당 해제된다

부모는 자식의 실행을 종료할 수 있다

  • 자식이 자신에게 할당된 자원을 초과하여 사용할 때
  • 자식에게 할당된 테스크가 더 이상 필요 없을 때
  • 부모가 exit하는데, 운영체제는 부모가 exit한 후에 자식이 실행을 계속하는 것을 허용하지 않는 경우 → cascading termination(연쇄식 종료 작업)

보통의 경우, 부모 프로세스가 종료된 후에 자식 프로세스가 존재할 수가 없다. 이 경우 부모가 종료되면 자식도 연달아 종료되는, 연쇄식 종료작업(cascading termination)이 시행된다.

부모 프로세스는 wait() 시스템 호출을 사용하여 자식 프로세스의 종료를 기다릴 수 있다. 호출은 종료된 프로세스의 상태 정보와 pid를 반환한다.

pid = wait(&status);

zombi

종료되었지만 부모 프로세스가 아직 살아있어서 wait() 호출을 하지 않은 프로세스

자식은 종료됐는데 부모가 아직 안끝난 경우

종료하게 되면 모든 프로세스는 좀비 상태가 되지만 아주 짧은 시간 동안만 머무른다.

orphan

부모 프로세스가 wait()를 호출하지 않고 종료한다면, 자식 프로세스들은 고아(orphan) 프로세스가 된다.

More About wait()

#include <sys/wait.h>
pid_t **wait**(int *wstatus); //ch3_p.31

프로세스가 상태를 바꿀때까지 기다린다

Multiprocess Architecture : Chrome Browser

대부분의 최신 웹 브라우저는 단일 프로세스로 실행한다

→ 한 웹 사이트에 문제가 생기면, 전체 브라우저가 충돌한다

Google Chrome 브라우저는 3가지 유형의 프로세스가 있는 multiprocess이다.

  • Browser 프로세스는 UI, 디스크 및 네트워크 I/O를 관리한다.
  • Renderer 프로세스는 웹 페이지를 렌더링하고, HTML, JavaScript를 처리한다. 열린 각각의 웹사이트에 대해 새로운 renderer가 생성된다.
  • Plug-in 프로세스는 유형별 플러그인 프로세스이다.


Interprocess Communication

시스템 내 프로세스는 독립적이거나 협력적일 수 있다.

프로세스 협렵을 하는 이유

  • 정보 공유
  • 계산 속도 증대
  • 모듈성

협력적 프로세스는 inter process communication(IPC)가 필요하다.

IPC의 두 가지 모델

  • Shared memory
    • 공유 메모리 모델에서는 협력 프로세스들에 의해 공유되는 메모리의 영역이 구축된다.

    • 프로세스들 사이에서 소통하기위해 공유된 메모리의 영역

    • 커뮤니케이션은 운영체제가 아닌 사용자의 프로세스의 통제하에 있다.

    • 주요 이슈는 그들이 공유 메모리에 접근할 때 동기화된 action을 취하는 것을 사용자 프로세스가 허락하도록 메커니즘을 제공하는 것이다

  • Message passing
    • 프로세스가 통신하고 그들의 작업을 동기화하기위한 메커니즘
    • 메세지 전달을 위해, 프로세스들 사이에 communication link가 존재해야 한다.
    • IPC가 제공하는 2가지 Operation
      • send(message)
      • receive(message)
    • (논리적인) 구현 방법
      • 직접/간접 (Direct/indirect)
      • 동기/비동기
      • 버퍼링 (0/bounded/unbounded capacity)

Producer-Consumer Problem (shared memory)

생산자와 소비자는 공유 메모리를 통해 정보를 통신한다.

생산자 : 소비자를 위해 정보를 생산한다

소비자 : 생산자가 기록한 정보들을 소비한다

ex) 컴파일러-어셈블러, 서버-클라이언트

⚠️ 생산자-소비자는 동기화(synchronized)되야한다

생산자와 소비자의 공유 메모리에 두 가지 버퍼가 사용되는데, 무한 버퍼(unbounded-buffer)는 크기에 실질적은 한계가 없고 생산자가 항상 생산할 수 있는 반면, 유한 버퍼(bounded-buffer)는 버퍼의 크기가 고정되어 있다고 가정한다. 버퍼가 가득차있다면 생산자는 기다려야한다.

Bounded Buffer

circular queue : 논리구조가 원형인 제한된 크기의 버퍼

마지막 요소 뒤에 첫번째 요소가 온다

BUFFER_SIZE -1 만큼 저장할 수 있다

#define BUFFER_SIZE 6

typedef struct {
	. . . 
} item;

item buffer[BUFFER_SIZE];
int in = 0; //tail or rear
int out = 0; //head or front

//inserting an item
buffer[in] = newItem;
in = (in + 1) %n;

//extracting an item
item = buffer[out];
out = (out + 1) %n;

//Empty/full condition
in == out : buffer is empty
(in+1)%BUFFER_SIZE == out : buffer is full

cf.buffer는 최대 버퍼 사이즈-1 크기의 값까지 저장할 수 있다. 

IMG_4122B89A1C8B-1.jpeg

queue 같음!! 앞에서부터 순차적으로 실행되고, 실행 후 삭제되면 그 다음 값이out(front)이 됨!!

/*shared_memory : 생산자*/
item next_produced;

while(1){
	//next_produced 위치에 아이템 생산
	while(((in + 1) % BUFFER_SIZE) == out); //full -> waiting
	buffer[in] = next_produced;
	in = (in + 1) % BUFFER_SIZE;
}
/*소비자*/
item next_produced;

while(1){
	//next)produced 위치에 아이템 생산
	while(in == out); //empty -> waiting
	next_consumed = buffer[out];
	out = (out + 1) % BUFFER_SIZE;
	//consume the item in next_consumed
}

(Message passing) 구현방법

1. 직접/간접 소통

직접 : 연결 링크가 직접 프로세스를 연결한다

간접 : 프로세스가 via mailbox로 연결된다

직접 소통

직접 소통

간접 소통

간접 소통

2. 동기화 (Synchronization)

Message passing은 blocking or non-blocking일 수 있다.

Blocking : 동기식 (wait function)

  • blocking send : 메세지가 수락될 때까지 발신자는 차단당한다.
  • blocking receive : 메세지가 가능할 때까지 수신자는 차단당한다.

Non-blocking : 비동기식

  • Non-blocking send : 발신자가 메세지를 보내고 계속한다.
  • Non-blocking receive : 수신자는 유효하거나 null 메세지를 받는다.

sender, receiver 모두 blocking일 경우 : Rendezvous(랑데뷰)

sender는 receiver를 기다려야 한다!!

예시

/*Message Passing : 생산자*/
message next_produced;

while(1){
	//next_produced 위치에 생산
	send(next_produced);
}
-------------------------------------------------
/*소비자*/
message next_consumed;

while(1){
	receive(next_consumed);
	// next_consumed에 있는 아이템을 소비한다
}

3. 버퍼링

소통 중에, 메세지는 임시 queue(buffer) 에 저장된다.

sendbufferreceive

버퍼 용량 3종류

  • 0 용량 : 아무 메세지도 queue되지 않는다
    • 발신자는 수신자를 기다려야 한다(랑데뷰)
  • bounded 용량 : 메세지 n개의 한정된 길이
    • link가 full이면, 발신자는 기다려야 한다
  • unbounded 용량 : 무한한 길이
    • 발신자는 기다릴 필요 없다

IPC의 예시 : Shared Memory

POSIX 공유 메모리

  • memory-mapped file을 통해 소통한다
  • 프로세스는 공유된 메모리 세그먼트를 생성하거나 연다.
  • object의 크기를 정한다
  • 공유 메모리 세그먼트를 프로세스 주소 공간으로 map한다
  • 프로세스는 공유된 메모리를 사용할 수 있게 된다.

Pipes

파이프는 두 프로세스가 통신할 수 있는 통로 역할을 한다.

Ordinary 파이프

  • 부모-자식 간의 한방향 소통
  • 일반적으로 부모 프로세스가 파이프를 만들고 생성된 자식 프로세스와 소통하기 위해 사용한다

Named 파이프

  • 양방향이며 부모-자식 관계가 불필요하다.

Ordinary Pipes

일반적인 파이프는 일반적인 생산자-소비자에서 한 방향 소통이 가능하다.

  • 생산자가 한쪽 끝으로 쓰기 시작한다.
  • 소비자가 다른 끝부터 읽기 시작한다.
  • 의사소통 프로세스 사이에 부모-자식 관계가 필요하다.

Window에서는 익명의 파이프라고 부른다.

Named Pipes

ordinary 파이프보다 더 강력하다.

  • 소통이 양방향이다
  • 의사소통 프로세스에서 부모-자식 관계가 불필요하다.
  • 몇몇 프로세스는 의사소통을 위해 named 파이프를 사용한다.
  • UNIX, Window 시스템에서 모두 제공된다.
  • UNIX 시스템 → FIFOs 라고 불린다.

(출처)
Operating System Concepts 도서
https://www.booksfree.org/operating-system-concepts-10th-edition-by-abraham-silberschatz-peter-b-galvin-greg-gagne-pdf/

profile
공부하는 기록

0개의 댓글