기초 물방울/리눅스&VM

리눅스(Linux) 프로세스와 시그널

Weeding 2022. 4. 5. 15:08
반응형
SMALL

Process

= 처리 과정 / 공정 / 진행

컴퓨터시스템에서의 프로세스는

컴퓨터가 일을 하게 하는 주체 를 의미

 

[실행중인 프로그램]

 

프로그램은 동작하고 있는 상태는 아니고 디스크에 저장되어있는 상태.

 

이게 실행이 되서 동작을 하면 = 실행중인 프로그램 = 프로세스

 

 

 

운영체제 관점에서

하드웨어와 애플리케이션 사이에 많은 것들을 해줘야하는 소프트웨어

 

운영체제의 중요한 역할이 바로

프로세스를 관리하는 일

 

사용자는 애플리케이션을 실행 했을 때 원하는 동작이 

기대되는데로 나오길 희망함.

 

이 때문에 프로세스가 잘 관리가 되어야함.

(운영체제 관점에서 많이 중요)

 

 

프로세스는 실제 정해진 일을 하게됨.

프로그램은 하드디스크에 저장만 되어있으면됨.

 

프로세스는 메모리 상에 존재함.

"프로세스는 메모리 상에 있는 객체"

 

프로그램은 하나이지만 

예를 들어 계산기는 여러개를 띄울 수 있음

프로세스는 여러개를 생성할 수 있음.

 

 

프로그램은 디스크에 저장되어있는 정적인 상태.

프로세스는 "동적"인 상태.

ex) 계산기들이 서로 다른 계산을 하는 행위 = 동적인행위/독립적

 

실질적으로는 CPU가 메모리상에 있는 프로세스들을 실행시켜줌 

stck, heap, code 등의 메모리 영역이 있음.

CPU는 프로세스들에 있는 실행 코드들을 가지고 동작을 시킴.

 

CPU가 프로세스를 실행시키면 프로그램과의 연관성은 없어짐.

 


 

프로세스 스케쥴링(process scheduling)

  • 여러 프로그램의 동시 실행
  • 어떻게 모두를 만족시킬 것인가?

 

프로세스 스케쥴링이란

"CPU의 관점에서 할일들을 정해주는 것"

[할일들 = 프로세스들을 실행해주는 것]

 

ex) 크롬도 띄우고, 엣지도 띄우고, 계산기도 사용하고

동시에 여러가지 사용을 할 때 CPU가 적절히 할일들을 정해주는게 중요함.

이것들을 결정해주는게 프로세스 스케쥴링 "알고리즘"

사용자 관점에서 모든것들을 만족시켜 주는 것이 좋은 알고리즘.

 

 

고성능을 요구하는 애플리케이션은

CPU가 많이 관여를 해야함.

 

계산기같은건 사용자의 입력에만 반응해주면됨.

 

요즘의 컴퓨터 시스템은 CPU가 하나만 있지 않음.

여러개가 있을 수 있는데.... [ex)삼성 휴대폰 옥타코어]

하나의 시스템에 CPU가 여러개 들어갈 수 있는

멀티코어, 멀티CPU 이러한 것들이 등장함.

 

 

CPU는 여러개의 프로세스들을 하나의 CPU가 스케쥴링해서 처리

1번 프로세스가 CPU에서 동작하는동안 나머지는 처리되길 기다림.

사람 입장에서는 다 동일하게 동작하는거라고 생각함.

(굉장히 빠르게 작동하는것임)

 

 

CPU 1번이 process 1번

CPU 2번이 process 4번

이런식으로 한 시점에 여러개의 프로세스가 처리가됨.

CPU 갯수가 늘어나는 만큼 성능이 늘어날 수 밖에 없음.

 

 

CPU의 코어클락이 중요해짐!

아주 예전에는 1GHZ 코어클락

2,3,4로 올라가게되면서 HZ가 올라가면 올라갈수록 성능도 올라감.

 

하나의 클락에서 동작을 올리게되면 온도가 올라감.

냉각시스템도 좋아져야하고 문제가 발생하기 시작해서

코어클락을 높이는 작업도 하지만, 극단적으로 10, 12로 올리지않고

코어의 갯수를 올리기 시작함

 

 


 

프로세스 상태(process state)

  • 프로세스 전이 다이어그램(process transition diagram)

 

프로세스마다 상태들을 관리해야할 필요가 있음.

그래야 CPU가 프로세스를 실행시킬 수 있음.

 

 

created

 

waiting

 

Running

 

Blocked 

프로세스가 외부에 있는 자원에 오퍼레이션하고 이것이 끝날때까지 기다리는 것

 

Terminated

 


 

프로세스 계층구조

 

PID(Process ID)

  • 여러가지의 프로세스들이 있을 때 프로세스들마다 유니크한 아이디 값을 가지고 있음.(숫자)
  • ex) 1,2,3,4,60000,60001 
  • 번호 자체가 갖는 의미는 없음. 
  • Unique ID를 갖는다는것 / 겹치는게 없다는것 

 

 

부모 프로세스와 자식 프로세스

  • 어떠한 한 프로세스가 다른 프로세스를 만들 수 있음.
  • 부모 프로세스 → 자식 프로세스(여러개 가능) → 자식프로세스
  • 위와 같은 형태를 항상 유지.
  • 모든 프로세스들은 부모 프로세스가 있음 
  • 단, init프로세스는 제외★

 

 

init프로세스

  • 실제 커널이 부팅을 시작
  • 커널이 하드웨어 자원들을 초기화(셋업)을 하고 프로세스와 관련한 초기를 함
  • 그 때 init프로세스라는걸 만듬 
  • 프로세스가 아무것도 없는 상황에서 최초로 하나의 프로세스를 만들어냄.
  • init프로세스는 항상 PID가 1번
  • Kernel이 init프로세스를 만들게 되고 부모프로세스가 없음.
  • 부모프로세스들도 init프로세스의 자식임.

 

 

★ 왜 이런 계층 구조를 갖게 했을까? ★

  • 프로세스 종료 처리 때문에 만듬.
  • 하나의 부모 프로세스가 자식 프로세스 하나를 만들었다라고 가정하면
  • 둘 다 따로따로 개별적으로 동작을 함. 이런 상태에서 자식 프로세스가 종료되면
  • 종료되는 프로세스들은 종료처리를 위해서 부모프로세스가 남은것들을 관리해주는데
  • 이러한 부분들 때문에 이러한 계층구조가 생기게 됨.

 

이러한 부분들이 잘 이뤄지지 않으면

"고아프로세스" "좀비프로세스" 가 생기게 됨.

 

ex) 부모프로세스가 종료되고 자식프로세스만 남게되면.

추후에 자식프로세스가 종료될 때 부모프로세스가 없기에

종료처리를 할 수 가 없음. 그래서 이러한 것들이 남게됨.

 

이 때 init이 고아 프로세스를 입양을 하게 됨.

부모프로세스를 init으로 바꿔줌.

(init프로세스는 리눅스 시스템 상에서 종료될 일이 없음.)

 

 

"좀비 프로세스"   

(고아 프로세스와 좀비 프로세스의 차이, 면접 때 단골질문)

 

부모프로세스 → 자식프로세스

자식프로세스가 종료된다고해서 부모프로세스가 자식프로세스의 관리를 다 잘 해주는것은 아님.

자식프로세스가 죽게 되면 운영체제가 부모 프로세스에게 Signal을 줌.

그러면 부모프로세스가 자식프로세스를 종료처리를 해 줄 수 있게 됨.

 

자식프로세스가 종료가 됬을 때 

부모프로세스 입장에서는

1. 죽기를 기다리거나

2. 시그널을 받으면 뒷처리를 해주는

 

이 둘 다를 안하는 것을 "좀비 프로세스" 라고 함.

종료처리를 해주지 않고 다른일을 하는것.

반쯤 종료된 상태로 종료되지 않고 기다리고 있는 자식 프로세스 = 좀비 프로세스

 

리눅스 시스템의 가용 자원에 영향을 끼치게 됨.

그래서 이러한 좀비프로세스의 발생이 없게 부모프로세스 개발을 잘 해야함.

 

 


 

프로세스 종료 상태 (exit status)

 

프로세스 종료 상태란?

  • 프로세스가 종료될 때 넘겨주는 정보
  • 부모 프로세스에게 정보를 넘기게 됨
  • 기본적으로는 "성공" "실패"를 판단할 수 있음 (자식프로세스가 어떻게 동작했는지)
  • 실패를 했다면 어떻게 실패했는지 알 수 있음.
  • ex) 성공했다면 새 프로세스를 만들고, 실패했다면 다른 방안 구상
  • ex) Shell에서 커맨드들을 실행하면 cp, ls같은 프로세스를 보여줌.
  • 여기에서는 Shell이 부모, ls명령어가 자식이 됨.
  • 종료 상태값은 integer(정수값)로 받게 됨.
  • 0 = 성공 / 0이 아닌 값 = 실패

 

 

상태정보 (종료상태값에 포함)

  • 정상 종료 여부
  • 시그널을 받아 종료되었는지 여부 및 시그널의 종류
  • 코어 덤프(core dump)를 생성햇는지 여부

 


 

표준 스트림(standard streams)

모든 프로세스가 가지고 있는 표준인 스트림.

모든 프로세스가 생성이 되면 각각의 프로세스는 표준 스트림이라고 하는 3가지 스트림을 가지고 생성됨.

각각의 프로세스가 입력/출력/에러 라고 불리는 3가지의 스트림을 가지고 있게됨.

 

 

1. 표준입력(standard input) 

  • 입력을 할 수 있는 창구
  • #0

 

2. 표준 출력(standard output)

  • 프로세스가 자신의 정보를 밖으로 내뱉는 것.
  • ex) ls 명령어를 사용했을 때 나오는 정보들 
  • #1

 

3. 표준 에러(standard erro)

  • ex) ls 뒤에 잘못된 명령어를 입력하면 나오는 정보들
  • #2

 

 

파일 디스크립터(file descriptor)

  • 프로세스가 파일을 열어서 데이터를 파일에 저장을 하든, 파일에 있는 데이터를 읽어 오든
  • 이렇게 파일에 무언가를 하고 싶을 때 필요한 객체
  • = 파일을 대변하는 객체
  • ex) Process → file /etc/passwd  
  •                → file ~~
  • 파일에 대한 작업(읽기/쓰기)을 하기 위해서는 파일 디스크립터를 열어야함.
  • 프로세스로 열린 파일 디스크립터 목록을 관리

 


 

프어그라운드 프로세스와 백그라운드 프로세스

 

 

포어그라운드 프로세스(Foreground process)

  • 쉘의 표준 입력이 연결된 프로세스
  • 표준 출력과 표준 에러도 쉘과 연결되어 있음
  • 기본적으로 뜨는 프로세스

 

백그라운드 프로세스(Background process)

  • 쉘의 표준 입력이 연결되지 않은 프로세스
  • 표준 출력과 표준 에러도 쉘과 연결되어 있음

 

쉘도 하나의 프로세스로 동작함.

ex) bash 프로세스가 ls라는 프로세스를 실행. ls실행이 끝나면 종료상태를 받아옴.

ls처럼 단시간에 실행이 되고 끝나는 프로세스 뿐 아니라

script를 만들어서 실행(오랫동안 하는 작업을 하는 스크립트라면)하면

이 script가 끝날때까지 기본적으로 bash가 기다려야함.

script가 표준입력(#0)을 사용자로부터 기다리고 있는 상태라면 (아이디 등록처럼)

이 script가 포어그라운드 프로세스라면 Shell하고 연결되어 있음.

사람이 키보드를 입력을하면 포어그라운드와 연결되어 있음.

 

 

ex) 어떤 또 다른 Script는 사용자의 입력이 없이 모니터링/감시만 하는 Script라면

사용자의 입력이 필요가 없기에, 이럴 때 백그라운드프로세스를 실행 시킬 수 있음.

여기에도 #0 표준입력이 있지만, 백그라운드에서는 이것과 연결시키지 않음.

 

 

하나의 Shell이 여러개의 프로세스를 실행할 수 있는데

이 때 포어그라운드와 백그라운드를 실행 시킬 수 있음.

 

bash가 실행할 수 있는 여러개의 프로세스들을

사용자의 입력이 필요한지 안한지에 따라서

포어와 백그라운드를 구분지어서 설정함.

 


 

데몬 프로세스(daemon process)

 

악마 프로세스

  • MIT 대학의 프로그래머가 만든 용어
  • "보이지 않는곳에서 어떤 일을 하는 유령"에서 영감을 받음.

 

데몬 프로세스는

  • 프로세스 자신이 뜨면서 자신을 데몬프로세스로 만듬.
  • 백그라운드 프로세스로 동작하기 위해 만들어진 프로세스 (아예 이런 목적을 가지고 만들어짐)
  • 표준 스트림을 갖고 시작하지만 프로세스가 자기 자신을 초기화 하는 도중에 모두 닫아 버림
  • → 쉘과의 입출력 교환 불가 (표준 출력 3가지를 모두 없애버림)
  • 부모 프로세스를 init 프로세스로 변경

 


 

시그널(signal)

  • 비동기(asynchronous) 이벤트를 처리하기 위한 프로세스간 통신
  • 프로세스간 통신(IPC) 중의 하나 ( socket, pipe 등등)
  • 동기 vs 비동기

 

 

Synchronous(동기)

  • 요청하는쪽, 응답을 받아오는 구조
  • 응답이 올 때까지 기다리는것

 

Asynchronous(비동기)

  • 다른일을 하다가 응답이 오면 그 때 반응

 

기본적으로 시그널 번호를 날려주게되는데 

어떤 종류의 시그널을 보낼건지 결정하게됨.

ex) 1번시그널이 왓네, 2번시그널이 왓네 이러한 것에 따라 방법이 정해짐.

signal handling이라고도 함 (프로그래밍 관점)

 

 

 

주요 시그널 종류

 

 


 

 

ps -f

 

ps -ef

 

ps -ef -forest

 

echo $$ 현재 프로세스

 

UID

PID

PPID

C

STIME

TIME CMD

 


echo $? 

 

이전 커맨드의 exit state를 받아올 수 있음

 

 

 


시그널 전송

shell 상에서 가장 많이 하는 행위

= 시그널을 보내는것

프로세스를 죽이는 방법

 

kill

 

sigkill 

차단이 불가능한 시그널 

 

kill -9

kill -term

 

kill -9 219957

 

 


포어그라운드 백그라운드 실습 마지막

 

포어그라운드 프로세스 

사용자의 입력이 필요한 경우나 그렇지 않은 대부분의 일반적인 경우

 

 

하나의 스크립트를 포어/백 나눠서 만들 수 도 있음.

 

 

포어

./process.sh 

 

./process.sh & 

 

fghello, pid 26028

 

ctrl+c

ctrl+z = 멈춤

 

fg = 다시 동작

bg  = 백그라운드로 실행 돌림

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형
LIST