Skip to main content

Command Palette

Search for a command to run...

Linux/Unix Lecture Notes: Managing Processes and CPU Resources

Published
28 min read
Linux/Unix Lecture Notes: Managing Processes and CPU Resources
H
Hi there, I'm a full time software engineering student, and full time mum based in Brisbane, QLD, Australia. Korean is my native language and English is my second, but I love learning software in English. My posts are a mix of both Korean and English, so there's something for everyone! All my posts come straight from my lecture notes, so follow along my study journey with me <3

리눅스/ 유닉스 시간의 교수님 녹취록입니다. 앞으로도 쭉 녹취록을 올릴것인데 모든 내용을 취합해서 블로그에 강의노트식으로 올릴예정입니다. 서술형으로 읽기 좋게 정리해주세요. 그리고 팩트체크도 해주세요. 추가설명은 필요없습니다. 테크니컬한 명사단어들과 제목은 영문으로도 표시해주세요. []

1️⃣ 프로세스 개요(Overview of Process)

프로세스(Process)와 프로그램(Program)의 차이

첫 번째로 다루는 개념은 프로세스(Process)프로그램(Program) 의 차이이다.
일상적으로는 두 용어를 크게 구분하지 않고 사용하는 경우가 많다. 하지만 전공 수업이나 운영체제(Operating System) 분야에서는 두 개념을 구분해서 사용한다.

일반적인 사용에서는 큰 차이가 없어 보일 수 있지만, 시스템을 이해하기 위해서는 프로그램과 프로세스를 나누어 생각해야 한다.


프로그램(Program)

프로그램은 기본적으로 스토리지(Storage) 에 저장되어 있는 상태를 의미한다. 여기서 스토리지는 디스크, SSD, USB, CD와 같은 저장장치를 포함한다.

프로그램은 결국 이러한 저장장치 안에 보관되어 있는 명령어(Instruction)들의 모임이다.

즉, 엔지니어가 프로그램을 작성하고 저장하면, 그것은 파일(File)의 형태로 스토리지에 존재하게 된다.

교수님은 프로그램의 특징을 다음과 같이 설명했다.

  • 스토리지에서 제거되기 전까지 계속 존재한다.

  • 파일 형태로 생성되고 보존된다.

  • 스토리지(Storage)에 저장된 상태이다.

  • 명령어들의 집합이다.

  • 파일(File) 형태로 존재한다.

  • 실행되기 전의 정적인 상태(static state)를 의미한다.

  • 프로세스(Process)와 구분하기 위해 CPU와 RAM을 사용하지 않는다고 설명한다.

여기서 “CPU와 RAM을 사용하지 않는다”는 표현은 절대적인 의미라기보다는, 프로세스(Process)와 구분하기 위한 설명이라고 강조했다. 실제로는 프로그램을 작성하거나 저장하는 과정 자체가 컴퓨터 위에서 이루어지므로 CPU와 RAM이 완전히 사용되지 않는 것은 아니다. 다만 운영체제 개념에서는, 저장장치에 보관된 정적인 상태(static state)의 대상을 설명하기 위해 이렇게 표현한다.


프로세스(Process)

그렇다면 프로세스(Process)는 무엇을 의미할까?

일상적으로는 프로그램과 프로세스를 거의 같은 의미처럼 사용하는 경우가 많다. 하지만 운영체제(Operating System)를 배우는 과정에서는 두 개념을 구분해서 이해해야 한다. 프로그램이 단순히 저장되어 있는 상태라면, 프로세스는 실제로 실행되면서 활동하고 있는 상태를 의미한다. 교수님 설명에서 가장 중요하게 강조된 부분은 다음이다.

프로세스는 CPU와 RAM을 사용하고 있으며, 그 안에서 존재하는 실행 단위이다.

앞에서 프로그램은 스토리지(Storage)에 저장되어 있는 명령어들의 집합이라고 설명했다. 디스크(Disk), SSD, USB 같은 저장장치 안에 파일(File) 형태로 존재하는 것이 프로그램이다. 이 상태의 프로그램은 정적인 상태(static state)에 가깝다.

반면 프로세스는 저장되어 있던 프로그램이 실제로 실행되면서 CPU와 RAM 자원을 사용하는 상태를 의미한다. 즉, 프로그램이 움직이기 시작한 순간부터 프로세스라는 개념으로 바라보게 되는 것이다.

교수님은 이 부분을 설명하면서 “CPU와 RAM에 존재해야 프로세스라고 말할 수 있다”고 표현했다. 결국 프로세스라는 개념은 단순히 저장된 파일이 아니라, 시스템 자원을 사용하며 실제로 동작하고 있는 상태를 나타내기 위해 등장한 것이다.


프로그램이 실행되는 과정도 함께 설명했다.

우리가 작성한 프로그램은 원래 스토리지에 저장되어 있다. 하지만 실행 버튼을 누르는 순간 운영체제(Operating System)는 그 프로그램을 메모리(RAM)로 옮긴다. 교수님은 이 과정을 “로드(load)”라고 설명했다.

여기서 load라는 표현은 단순히 데이터를 읽는다는 의미보다, 실제로 짐을 옮기는 것에 가까운 개념이라고 설명했다. 예를 들어 창고에 있던 물건을 배송 차량으로 옮기는 것처럼, 스토리지에 저장되어 있던 프로그램 코드가 RAM으로 이동하는 것이다.

즉 프로그램 실행 과정은 다음과 같이 이해할 수 있다.

스토리지(Storage)에 저장되어 있던 프로그램이 실행 요청을 받으면, 운영체제가 해당 프로그램을 RAM으로 적재(load)한다. 이후 CPU는 RAM에 올라온 명령어와 데이터를 읽어 연산을 수행한다. 그리고 이 데이터들은 CPU 내부의 Cache나 Register 같은 구성 요소를 오가며 처리된다.

교수님은 특히 Register를 언급하면서, CPU 안에서 매우 빠르게 데이터를 주고받으며 연산이 이루어진다고 설명했다. 결국 이러한 과정이 반복되면서 화면 출력이나 계산 결과처럼 사용자가 직접 확인할 수 있는 결과가 만들어진다.

또한 프로세스는 메모리 안에서 여러 영역으로 나뉘어 동작한다고 설명했다. 대표적으로 다음과 같은 구조를 가진다.

  • 코드(Code)

  • 데이터(Data)

  • 스택(Stack)

  • 힙(Heap)

즉 프로세스는 단순히 “실행 중이다”라는 의미만 가지는 것이 아니라, 메모리 안에서 여러 영역을 구성하며 체계적으로 동작하는 실행 단위라고 볼 수 있다.


동시 실행(Concurrent Execution)과 작업(Job)

앞에서는 프로그램(Program)과 프로세스(Process)의 차이를 구분해서 살펴보았다.
이번에는 그 개념에서 이어져, 컴퓨터가 실제로 어떻게 여러 작업을 실행하는지와 Job이라는 표현에 대해 설명한다. 교수님은 먼저 하나의 질문을 던졌다.

컴퓨터는 한 번에 하나의 프로그램만 실행할까, 아니면 동시에 여러 개를 실행할까?

결론부터 말하면 컴퓨터는 여러 작업을 동시에 실행하고 있다. 스마트폰 역시 마찬가지이다.

우리가 스마트폰이나 컴퓨터를 사용할 때는 보통 하나의 화면만 집중해서 보고 있기 때문에, 마치 하나의 프로그램만 실행되는 것처럼 느껴질 수 있다. 하지만 실제 내부에서는 브라우저, 메신저, 음악 재생, 네트워크 처리, 운영체제 서비스 등 수많은 프로그램이 동시에 동작하고 있다.

물론 사용자가 직접 인터랙션(interaction)하고 있는 프로그램은 보통 하나처럼 보인다. 예를 들어 키보드를 입력하거나 화면을 터치할 때는 현재 활성화된 프로그램만 눈에 띈다. 그러나 동영상을 띄워두거나 여러 창(window)을 동시에 배치하면, 여러 프로그램이 함께 동작하고 있다는 사실을 더 쉽게 확인할 수 있다.

Job(작업)의 의미

이 과정에서 교수님은 Job(작업) 이라는 표현을 소개했다.

Job이라는 용어는 초기 컴퓨터 역사에서 유래했다고 설명했다. 과거에는 사람이 펀치카드(Punch Card)를 사용하여 컴퓨터에 작업을 요청했고, 컴퓨터는 이를 순서대로 처리하는 배치 처리(Batch Processing) 방식을 사용했다. 여기서 하나의 작업 단위를 Job이라고 부르게 된 것이다.

교수님은 컴퓨터 용어 중 상당수가 원래 사람이 일하던 환경에서 가져온 표현이라고 설명했다. 컴퓨터는 결국 사람의 일을 대신 처리하는 기계이기 때문에, 실제 인간 사회에서 사용되던 용어들이 컴퓨터 분야로 자연스럽게 넘어왔다는 것이다.

예를 들어 전공자들은 “함수(Function)”라는 말을 들으면 프로그래밍 개념을 먼저 떠올리지만, 다른 분야 사람들은 전혀 다른 의미를 생각할 수도 있다. 이처럼 컴퓨터 분야에서는 특정 단어가 거의 고유명사처럼 사용되지만, 원래는 일반적인 의미를 가진 용어였다는 점을 강조했다.

하나의 Job과 여러 개의 프로세스

교수님은 하나의 작업(Job)이 반드시 하나의 프로세스(Process)만 의미하는 것은 아니라고 설명했다. 하나의 작업(Job)은 하나 이상의 프로세스로 구성될 수 있다. 앞에서 프로세스는 CPU와 RAM을 사용하며 실제로 동작하고 있는 살아있는 상태라고 설명했다. 이러한 프로세스 여러 개를 하나로 묶어서 하나의 Job으로 볼 수 있다는 것이다.

  • 프로세스(Process) → 실제 실행 단위

  • 잡(Job) → 사용자 입장에서 묶어서 바라보는 작업 단위라고 이해할 수 있다.

커널(Kernel) 관점과 사용자(User) 관점

교수님은 프로세스와 잡을 구분하는 또 다른 기준으로 “누가 관리하느냐”를 설명했다. 프로세스(Process)는 운영체제의 커널(Kernel) 관점에서 추적하고 관리하는 대상이다. 반면 Job은 사용자(User)나 쉘(Shell) 관점에서 관리하는 작업 단위이다.

즉 운영체제 내부에서는 각각의 프로세스를 개별적으로 관리하지만, 사용자는 여러 프로세스를 하나의 작업처럼 다루게 되는 경우가 있다는 의미이다.

이 때문에 각각 다른 식별자(identifier)를 사용한다.

  • 프로세스 → PID(Process ID)

  • 작업(Job) → JID(Job ID)

교수님은 여기서 “왜 이렇게 비슷한 개념을 계속 세분화하는가?”라는 의문이 생길 수 있다고 설명했다. 하지만 전공이나 전문 분야로 갈수록 더욱 세밀한 구분이 필요해진다고 말했다.

예를 들어 우리가 일상적으로는 모두 “쌀”이라고 부르지만, 실제로는 품종과 특성이 매우 다양하게 나뉘는 것과 비슷한 개념이라고 설명했다.

백그라운드(Background) 실행

마지막으로 교수님은 Job이라는 표현이 보통 백그라운드(background)에서 실행되는 프로그램을 의미하는 경우가 많다고 설명했다. 여기서 백그라운드는 사용자가 직접 화면에서 조작하지 않아도 뒤에서 계속 실행되는 상태를 의미한다.

그리고 이에 대비되는 개념이 바로 포어그라운드(Foreground)이다. Foreground는 사용자가 현재 직접 상호작용(interaction)하고 있는 실행 상태를 의미하며, 이에 대한 내용은 다음 슬라이드에서 이어서 설명한다고 언급했다.


동시 실행과 포어그라운드(Foreground)

프로그램과 프로세스(Process)의 차이를 이해했다면, 이제 실제 컴퓨터가 어떻게 여러 작업을 처리하는지 자연스럽게 이어서 생각해볼 수 있다. 컴퓨터는 한 번에 하나의 프로그램만 실행하는 것처럼 보이기도 하지만, 실제로는 여러 작업이 동시에 실행되고 있다.

스마트폰만 보더라도 쉽게 알 수 있다. 사용자는 현재 하나의 앱 화면만 보고 터치하고 있을 수 있지만, 그 뒤에서는 음악 재생, 네트워크 통신, 알림 처리, 메신저, 운영체제 서비스 등 수많은 프로그램이 함께 동작하고 있다. 컴퓨터 역시 마찬가지이다.

다만 사용자가 직접 보고 상호작용(interaction)하는 프로그램은 보통 하나처럼 느껴진다. 특히 리눅스(Linux) 터미널(Terminal) 환경에서는 이러한 특징이 더욱 뚜렷하게 보인다.

리눅스 서버에 접속하면 흔히 검은 화면의 문자 기반 환경을 보게 된다. 사용자는 쉘(Shell)에 명령어(command)를 입력하고 엔터(Enter)를 누른다. 그러면 프로그램이 실행되고, 실행이 끝나면 다시 입력을 기다리는 상태로 돌아간다. 이때 화면에는 깜빡이는 커서(cursor)가 나타난다.

보통 우리가 예제로 실행하는 프로그램들은 수행 시간이 매우 짧다. 그래서 명령을 입력하면 곧바로 결과가 출력되고 다시 프롬프트(prompt)가 나타난다. 이러한 흐름에 익숙해지다 보니, 자연스럽게 “현재 실행 중인 작업이 끝나야 다음 입력을 할 수 있다”는 방식으로 터미널 환경을 이해하게 된다.

즉 기본적인 쉘 환경은 다음과 같은 흐름으로 동작한다.

  1. 사용자가 명령어를 입력한다.

  2. 프로그램이 실행된다.

  3. 실행이 종료된다.

  4. 다시 입력 대기 상태로 돌아간다.

이 구조만 보면 하나의 터미널에서는 동시에 여러 작업을 할 수 없는 것처럼 느껴질 수 있다. 하지만 실제로는 그렇지 않다.

Ctrl + Z 와 작업(Job) 제어

쉘 환경에서는 실행 중인 프로그램을 일시적으로 멈출 수도 있다. 대표적인 방법이 Ctrl + Z 이다.

실행 중인 프로그램에서 Ctrl + Z를 입력하면 현재 작업이 중단(suspend)된다. 중요한 점은 프로그램이 종료되는 것이 아니라, 실행이 멈춘 상태로 유지된다는 것이다.

중단된 작업들은 jobs 명령어를 통해 확인할 수 있다.

이러한 방식은 GUI(Graphical User Interface)에 익숙한 사용자들에게는 다소 낯설 수 있다. 일반적인 데스크톱 환경에서는 여러 창(window)을 띄워놓고 프로그램을 동시에 실행하기 때문에, foreground나 background를 직접 의식하지 않는 경우가 많다.

하지만 현재 다루는 CLI(Command Line Interface) 환경은 하나의 터미널 창 안에서 여러 작업을 관리해야 하는 구조이다. 그래서 작업을 어떻게 중단하고, 다시 실행하며, 앞에서 실행할지 뒤에서 실행할지를 구분하는 개념이 중요해진다.

Foreground와 Background

이 과정에서 등장하는 개념이 바로 Foreground와 Background이다.

Foreground(포어그라운드)는 사용자가 현재 직접 상호작용하고 있는 상태를 의미한다. 키보드 입력을 받고 화면에 결과를 출력하며, 사용자가 “지금 보고 있는 작업”이라고 생각하면 이해하기 쉽다. 반면 Background(백그라운드)는 사용자가 직접 보고 있지는 않지만 뒤에서 계속 실행되고 있는 상태를 의미한다.

예를 들어 현재 터미널에서 직접 실행 중인 프로그램은 foreground 작업이고, 뒤에서 계속 동작하도록 돌려놓은 프로그램은 background 작업이 된다.

이처럼 하나의 작업 공간 안에서도 “앞에서 실행되는 작업”과 “뒤에서 실행되는 작업”이 나뉘어 존재하게 된다.

fgbg 명령어

중단된 작업은 다시 실행할 수도 있다.

fg 명령어를 사용하면 작업을 foreground 상태로 가져와 다시 실행할 수 있고, bg 명령어를 사용하면 background 상태에서 계속 실행되도록 만들 수 있다.

Ctrl + Z로 잠시 멈춘 프로그램을 다시 앞에서 실행할 수도 있고, 사용자가 다른 작업을 계속할 수 있도록 뒤에서 실행시킬 수도 있는 것이다.

이러한 기능은 하나의 터미널 환경 안에서도 여러 작업을 효율적으로 관리할 수 있게 해준다.

Job 번호(Job ID)

쉘(Shell)은 여러 작업(Job)을 동시에 관리할 수 있기 때문에, 각 작업에는 번호가 부여된다. 이를 Job ID(JID)라고 한다.

사용자는 이 번호를 기준으로 어떤 작업이 실행 중인지, 어떤 작업이 중단되었는지, 어떤 작업을 foreground나 background로 전환할 것인지 관리하게 된다.

앞에서 프로세스(Process)가 운영체제 커널(Kernel) 관점에서 관리되는 실행 단위였다면, Job은 사용자와 쉘 관점에서 관리되는 작업 단위라고 볼 수 있다.


동시 실행과 백그라운드(Background)

백그라운드(Background)는 사용자가 직접 보고 입력하지는 않지만, 뒤에서 계속 실행되고 있는 작업을 의미한다. 즉 백그라운드 프로세스(background process)로 실행되는 프로그램을 백그라운드 작업이라고 부른다.

리눅스(Linux)나 유닉스(UNIX) 쉘(Shell)에서는 명령어 뒤에 &를 붙이면 프로그램을 백그라운드로 실행할 수 있다.

예를 들어 일반적으로 프로그램을 실행하면 해당 작업이 끝날 때까지 터미널을 사용할 수 없다. 하지만:

command &

처럼 실행하면 프로그램은 뒤에서 계속 동작하고, 사용자는 바로 프롬프트(prompt)를 다시 받아 다른 명령을 입력할 수 있게 된다. 즉 터미널의 제어권(control)을 다시 돌려받는 것이다.

하지만 백그라운드 작업도 화면 출력(output)을 할 수 있다. 프로그램이 표준출력(Standard Output)을 사용하면, 뒤에서 실행 중이어도 터미널 화면에 내용이 출력될 수 있다.

이 경우 사용자가 다른 작업을 하고 있는데 갑자기 로그나 메시지가 화면에 출력되어 작업 흐름을 방해할 수 있다.

이를 막기 위해 사용하는 설정이:

stty tostop

이다. 이 설정을 사용하면 백그라운드 작업이 터미널 화면에 출력하려고 할 때 해당 작업을 정지(stop)시킬 수 있다. 즉 백그라운드 프로그램이 터미널을 함부로 사용하는 것을 막는 역할을 한다.


동시 실행과 데몬(Daemon)

데몬(Daemon)은 사용자가 직접 상호작용(interaction)하지 않는 상태에서 뒤에서 계속 실행되는 프로그램을 의미한다. 즉 사용자가 키보드로 입력하거나 화면을 직접 조작하지 않아도 시스템 내부에서 지속적으로 동작하는 프로세스(process)이다.

보통 데몬은 백그라운드(background) 프로세스 형태로 실행된다. 사용자는 존재를 크게 의식하지 않지만, 시스템 기능을 유지하거나 특정 서비스를 제공하기 위해 계속 동작하고 있다.

예를 들어 서버(server) 기능이나 네트워크(network) 관련 서비스들도 대부분 이러한 방식으로 동작한다.

데몬 프로그램은 관습적으로 이름 끝에 d가 붙는 경우가 많다. 예를 들어 일반 프로그램이:

hello.c

처럼 작성된다면, 데몬 형태로 동작하는 프로그램은:

hellod

또는 이름 끝에 d를 붙이는 방식으로 표현하는 경우가 많다. 다만 이는 어디까지나 관습(convention)일 뿐이며, 반드시 그렇게 해야 하는 것은 아니다.

또한 데몬은 보통 시스템이 시작될 때부터 함께 실행되며, 오랫동안 지속적으로 동작한다. 이 과정에서 관리자 권한인 root 권한으로 실행되는 경우도 많다.

즉 데몬은:

  • 사용자가 직접 조작하지 않고

  • 백그라운드에서 실행되며

  • 시스템 시작과 함께 동작하고

  • 장시간 계속 실행되는 프로그램이라고 이해할 수 있다.


📌데몬(Daemon)과 백그라운드(Background)의 차이

데몬(Daemon)과 백그라운드(Background)는 모두 뒤에서 실행된다는 공통점이 있지만, 완전히 같은 개념은 아니다.

백그라운드 프로세스는 단순히 사용자가 직접 제어하지 않고 뒤에서 실행되고 있는 모든 프로그램을 의미한다. 예를 들어 &를 붙여 실행한 프로그램이나, 터미널에서 직접 보고 있지 않지만 계속 동작 중인 작업들이 모두 백그라운드에 해당할 수 있다.

반면 데몬(Daemon)은 그중에서도 특정한 특징을 가진 프로그램을 따로 부르는 이름이다. 즉 백그라운드 프로세스라는 큰 범주 안에 데몬이라는 개념이 포함된다고 볼 수 있다. 데몬은 단순히 “뒤에서 실행되는 프로그램”이 아니라, 시스템 기능을 위해 계속 동작하는 백그라운드 프로그램이라고 이해할 수 있다.

또 하나 중요한 점은 용어 사용에서 “프로그램”과 “프로세스”가 혼용된다는 것이다.

데몬을 설명할 때도 “백그라운드 프로세스로 실행되는 프로그램”이라는 표현을 사용했는데, 이는 실제로는 같은 대상을 서로 다른 관점에서 부르는 것이다.

  • 프로그램(Program) → 저장된 실행 파일

  • 프로세스(Process) → 실행 중인 상태

하지만 실제 설명에서는 두 용어가 문맥에 따라 혼용되는 경우가 많다. 데몬 역시 “프로그램”이라고 부르기도 하고 “프로세스”라고 부르기도 한다.

결론적으로 정리하면 다음과 같다.

  • 백그라운드: 뒤에서 실행되는 모든 작업

  • 데몬: 그중에서도 시스템 서비스처럼 지속적으로 동작하는 특수한 백그라운드 프로세스

  • 프로그램/프로세스: 문맥에 따라 혼용되지만, 엄밀히는 실행 전/실행 중 상태의 차이

이처럼 운영체제(Operating System) 개념에서는 용어가 엄격하게 나뉘어 있지만, 실제 설명이나 시험에서는 문맥에 따라 서로 섞여 사용되기도 한다. 따라서 “같은 의미로도 쓰이지만, 구분하면 다르다”는 관점으로 이해하는 것이 중요하다.


프로세스 정보 확인: ps(process status) (1/3)

ps(process status) 명령어는 현재 실행 중인 프로세스(Process)의 상태를 확인하는 데 사용된다. 즉, 특정 시점에서 시스템 안에서 어떤 프로세스들이 동작하고 있는지를 보여주는 도구이다.

PID (Process ID)

각 프로세스는 생성될 때 고유한 ID를 부여받는다. 이를 PID(Process ID)라고 한다. 컴퓨터는 기본적으로 모든 대상을 숫자로 구분한다. 사람은 이름으로 구분하는 것이 익숙하지만, 컴퓨터는 효율적인 처리를 위해 숫자 기반으로 식별한다. 프로세스도 마찬가지로 각각 고유한 숫자 ID를 가진다. 이 PID는 프로세스가 생성되는 순서에 따라 부여되며, 시스템 환경에 따라 표현할 수 있는 범위가 달라진다. 예를 들어 32비트 시스템과 64비트 시스템은 처리 가능한 숫자의 범위와 관리 방식이 다를 수 있다.

PID 범위와 관리

리눅스(Linux)에서는 PID의 최대값을 확인할 수 있다.

cat /proc/sys/kernel/pid_max

이 값은 시스템 설정에 따라 달라지며, 생성 가능한 PID의 최대 범위를 의미한다.

예를 들어 최대값이 100이라고 가정했을 때, 프로세스가 계속 생성되어 100을 초과하면 단순히 0으로 돌아가는 방식이 아니라, 사용 가능한 다른 번호를 찾아 할당하게 된다.

즉 PID는 순환 구조처럼 보일 수 있지만, 실제로는 시스템이 사용 가능한 번호를 재배치하는 방식으로 관리된다.

PID 0과 1

리눅스 시스템에는 특별한 PID가 존재한다.

  • PID 0: swapper / idle task (kernel thread)

  • PID 1: init (또는 systemd 등 초기 사용자 공간 프로세스)

PID 0은 시스템 내부에서 CPU가 할 일이 없을 때 동작하는 idle 상태와 관련된 커널(kernel) 프로세스이다. 일반적으로 사용자에게 직접 보이는 프로세스는 아니다.

PID 1은 시스템이 부팅될 때 가장 먼저 실행되는 기본 프로세스로, 이후 다른 모든 프로세스의 시작점이 된다.

부모-자식 구조 (PPID)

프로세스에는 부모-자식 관계가 존재한다. 이를 나타내는 것이 PPID(Parent Process ID)이다.

즉 새로운 프로세스는 기존 프로세스에 의해 생성되며, 이 관계를 통해 시스템은 프로세스 구조를 트리(tree) 형태로 관리한다.

ps 명령 출력 정보

ps 명령을 실행하면 다음과 같은 정보들이 함께 출력된다.

  • PID (Process ID)

  • TTY (Terminal Type)

  • TIME (CPU 사용 시간)

  • CMD / COMMAND (실행된 명령어)

이 정보들을 통해 현재 어떤 프로세스가 실행되고 있는지, 어떤 터미널에서 실행되었는지, 어떤 명령으로 시작되었는지를 확인할 수 있다.

의미 정리

ps 명령은 단순히 프로세스 목록을 보여주는 것이 아니라, 시스템이 현재 어떤 작업들을 어떤 PID로 관리하고 있는지를 확인할 수 있는 도구이다.

즉 컴퓨터 내부에서는 모든 실행 단위가 숫자(PID)로 관리되고 있으며, 이를 통해 프로세스를 추적하고 제어할 수 있다.


ps 추가 설명 (Additional Explanation of ps (process status)) (2/3)

ps(process status) 명령어를 사용하면 현재 실행 중인 프로세스(Process)의 다양한 정보를 확인할 수 있다. 단순히 어떤 프로세스가 실행 중인지뿐만 아니라, 언제 시작되었고 어떤 상태로 동작하고 있는지도 함께 볼 수 있다.

그중 STIME 또는 START 항목은 프로세스의 시작 시간을 의미한다. 최근에 실행된 프로세스는 시간 형태로 표시되지만, 24시간 이상 지난 프로세스는 시간 대신 날짜 형태로 출력된다.

예를 들어 어떤 프로세스가 아주 오랫동안 실행 중이라고 해서, ps 명령이 “3000시간째 실행 중” 같은 정보를 자세하게 보여주지는 않는다. 애초에 ps는 현재 시점의 상태를 간단하게 확인하기 위한 도구이기 때문이다. 따라서 오래 실행된 프로세스는 “언제 시작되었는가” 정도만 표시해주는 방식으로 동작한다.

또 다른 중요한 항목은 STAT이다. 이는 현재 프로세스의 상태(state)를 나타낸다.

프로세스는 단순히 실행 중인 것만이 아니라, 대기(waiting), 중단(stopped), 실행(running) 등 여러 상태를 가질 수 있다. STAT 항목은 이러한 현재 상태를 문자 형태로 보여준다.

특히 BSD 형식의 ps 출력에서는 추가적인 상태 표시가 함께 붙기도 한다.

예를 들어: <, N, L, s, l, +

같은 문자들이 나타날 수 있는데, 이는 프로세스의 우선순위(priority), 세션(session) 여부, 멀티스레드(multithread) 상태 등 다양한 특성을 나타낸다.

STAT는 단순히 “실행 중인가?”만 표시하는 것이 아니라, 현재 프로세스가 어떤 특성을 가진 상태인지까지 표현하는 정보라고 볼 수 있다.

이러한 프로세스 상태 개념은 운영체제(Operating System) 수업에서 더 자세히 다루게 된다. 운영체제 이론에서는 보통 프로세스 상태를 3단계, 5단계 등으로 나누어 설명한다.

예를 들어:

  • 실행(Running), 준비(Ready), 대기(Waiting)

같은 형태로 구분한다. 하지만 실제 리눅스(Linux) 시스템에서 확인하는 상태와 운영체제 교과서에서 배우는 개념은 완전히 같지는 않을 수 있다.

이는 실제 운영체제가 이론적인 모델을 그대로 사용하는 것이 아니라, 시스템 발전 과정에서 불필요한 기능이 제거되거나 새로운 기능이 추가되고 성능 개선이 이루어졌기 때문이다.

즉 운영체제 수업에서 배우는 상태 모델은 개념 이해를 위한 구조이고, 리눅스는 이를 실제 시스템 환경에 맞게 구현하고 발전시킨 결과라고 이해할 수 있다.


Showing Current Process Status with ps (3/3)

ps(process status) 명령어는 현재 시점에서 실행 중인 프로세스(Process)의 상태를 보여준다. 이때 출력되는 정보에는 메모리 사용량, CPU 사용률, 프로세스 그룹 정보 등 다양한 항목이 포함된다.

RSS (Resident Set Size)

RSS(Resident Set Size)는 현재 프로세스가 실제로 사용 중인 물리 메모리(physical memory)의 크기를 의미한다. 보통 1000-byte 단위로 표시된다.

즉 프로세스가 RAM 안에서 실제 점유하고 있는 메모리 양이라고 이해할 수 있다.

VSZ (Virtual Memory Size)

VSZ(Virtual Memory Size)는 프로세스가 사용하는 가상 메모리(virtual memory)의 전체 크기를 의미한다. 일반적으로 1024-byte 단위로 표시된다.

이는 실제 물리 메모리만이 아니라, 프로세스가 사용할 수 있도록 할당된 가상 주소 공간까지 포함한 개념이다.

%CPU

%CPU는 해당 프로세스가 사용하는 CPU 비율을 의미한다. 이는 CPU time과 실제 경과 시간(real time)의 비율을 기준으로 계산된다. 즉 특정 프로세스가 전체 시간 중 얼마나 CPU를 사용하며 동작했는지를 보여주는 값이다.

%MEM

%MEM은 시스템의 전체 물리 메모리 대비 현재 프로세스의 RSS 비율을 의미한다. 즉 컴퓨터 전체 메모리 중에서 현재 프로세스가 얼마나 메모리를 사용하고 있는지를 퍼센트(%) 형태로 보여주는 항목이다.

PGID (Process Group ID)

PGID(Process Group ID)는 프로세스 그룹(Process Group)을 구분하기 위한 번호이다.

만약 PID와 PGID가 같다면, 해당 프로세스는 프로세스 그룹의 리더(leader)라는 의미가 된다.

즉 하나의 프로세스 그룹 안에서도 중심이 되는 프로세스가 존재할 수 있다는 뜻이다.

ps 명령의 특징

ps 명령어는 실시간으로 계속 업데이트되는 방식이 아니다. 사용자가 ps를 입력하고 엔터(Enter)를 누르는 순간, 바로 그 시점의 프로세스 상태만 출력한다. 즉 현재 상태를 “순간적으로 캡처(snapshot)”해서 보여주는 방식이다. 그래서 프로세스 상태가 빠르게 변하는 상황에서는:

“왜 방금 본 상태와 다르지?”

처럼 느껴질 수도 있다. 하지만 리눅스(Linux)에서는 프로세스 상태를 지속적으로 갱신해서 볼 수 있는 방법들도 함께 제공된다. 즉 ps는 현재 상태를 한 번 확인하는 용도이고, 실시간 모니터링을 위한 별도의 도구들도 존재한다.


ps 주요 옵션/선택 (Major ps Options)

ps(process status) 명령어는 단순히 ps만 입력해서 사용할 수도 있지만, 실제로는 다양한 옵션(option)을 함께 사용해 원하는 형태의 프로세스(Process) 정보를 확인하게 된다. 리눅스(Linux)나 유닉스(UNIX)에서는 보통 - 뒤에 알파벳 옵션을 붙여 사용한다.


ps -f

-f 옵션은 full-format 형식으로 프로세스 정보를 출력한다. 기본 출력보다 더 많은 정보를 보여주며, 실행된 명령어의 인수(argument)까지 함께 확인할 수 있다. 즉 단순히 어떤 프로그램이 실행 중인지뿐만 아니라, 어떤 옵션과 함께 실행되었는지도 볼 수 있다.

ps -u username

-u 옵션은 특정 사용자의 모든 프로세스를 보여준다. 즉 어떤 사용자가 현재 어떤 작업을 하고 있는지 확인할 수 있다는 의미가 된다. 리눅스와 유닉스는 기본적으로 여러 사용자가 함께 사용하는 환경을 전제로 설계된 시스템이다. 그래서 기본 설정 상태에서는 다른 사용자의 정보에 접근 가능한 경우도 존재한다. 예를 들어 권한(permission)을 적절히 설정하지 않으면, 같은 시스템을 사용하는 다른 사람이 파일이나 작업 내용을 확인할 가능성도 있다. 따라서 시스템 관리자(admin)는 사용자 권한과 개인정보 보호 설정을 중요하게 관리해야 한다.

ps -e

-e 옵션은 시스템 전체의 모든 프로세스를 보여준다. 즉 현재 운영체제(Operating System) 안에서 실행 중인 전체 작업 목록을 확인할 수 있다.

ps -t pts/0

-t 옵션은 특정 터미널(terminal)에서 실행 중인 프로세스만 보여준다. 처음에는 “특정 터미널만 따로 볼 필요가 있을까?”라는 생각이 들 수 있지만, 실제로는 여러 터미널 창을 동시에 사용하는 경우가 많다. 예를 들어 하나의 컴퓨터에서 여러 터미널 창을 띄우고 각각 로그인하여 작업할 수 있다. 이 경우 각 터미널마다 어떤 프로세스가 실행 중인지 따로 확인해야 하는 상황이 생긴다. 즉 터미널은 단순히 하나의 모니터 화면 개념이 아니라, 여러 개의 독립적인 작업 공간처럼 사용할 수 있는 것이다.

ps x

x 옵션은 TTY(제어 터미널)가 없는 프로세스까지 포함해서 보여준다. 일반적인 foreground 작업뿐만 아니라, background 프로세스나 데몬(daemon)처럼 터미널과 직접 연결되지 않은 작업들도 확인할 수 있게 된다.


프로세스 정보: kill Process Information, kill

kill 명령어는 단순히 프로세스를 “강제로 종료하는 명령”으로 많이 알려져 있지만, 실제 의미는 조금 더 넓다. 리눅스(Linux)나 유닉스(UNIX)에서 kill은 프로세스(Process)에 시그널(signal)을 보내는 명령어이다.

Signal(시그널)

Signal은 말 그대로 프로세스에게 전달되는 “신호”이다. 실행 중인 프로세스가 작업을 수행하고 있을 때, 외부에서 특정 신호를 끼워 넣어 동작에 영향을 주는 방식이다. 이러한 개념은 인터럽트(interrupt)와 비슷하게 설명되기도 한다. 즉 프로세스가 계속 실행 중일 때 운영체제나 사용자가 특정 signal을 보내면, 프로세스는 그 신호에 맞게 반응하게 된다.

kill -L

kill -L

kill -L 명령을 입력하면 시스템에서 사용할 수 있는 signal 목록을 확인할 수 있다. 예시에서는 약 64개의 signal이 보일 수 있지만, 이것이 절대적인 숫자를 의미하는 것은 아니다. 시스템 환경이나 운영체제 버전에 따라 제공되는 signal 종류와 개수는 달라질 수 있다.

kill의 실제 의미

이름 때문에 kill은 단순히 프로세스를 제거(delete)하거나 종료시키는 명령처럼 보일 수 있다. 하지만 실제로는 특정 signal을 프로세스에 전달하는 역할을 한다.

  • kill → signal을 보냄

  • 프로세스 → signal을 받고 반응함

이라는 구조로 동작한다. 컴퓨터는 signal 종류를 각각 구분할 수 있도록 설계되어 있으며, 프로세스는 전달받은 signal에 따라 서로 다른 동작을 수행한다.

예를 들어: 종료, 일시 중단, 재시작, 무시, 사용자 정의 처리

등 다양한 반응이 가능하다. 즉 kill은 “무조건 종료시키는 명령”이 아니라, 프로세스에게 특정 signal을 전달하는 도구라고 이해하는 것이 더 정확하다.


kill의 사용 형식 (kill Command Usage)

kill 명령어는 프로세스(Process)에 특정 시그널(signal)을 보내기 위해 사용된다.

기본 형식은 다음과 같다.

kill [option] <pid>

여기서 pid는 signal을 전달할 대상 프로세스의 PID(Process ID)를 의미한다.

기본 시그널: TERM(15)

kill 명령에서 별도의 signal을 지정하지 않으면 기본적으로 TERM(15) signal이 전달된다.

kill 100

처럼 입력하면 실제로는:

kill -TERM 100

과 같은 의미로 동작한다. 여기서 15는 signal 번호이며, 앞에서 확인했던 여러 signal 목록 중 하나이다.

시그널 지정 방법

Signal은 숫자(number)와 이름(name) 둘 다 사용할 수 있다. 예를 들어 다음 표현들은 모두 signal을 지정하는 방식이다.

kill -9 PID
kill -SIGKILL PID
kill -KILL PID

즉 signal은: 숫자 형태, 전체 이름 형태, 축약 이름 형태 모두 사용할 수 있다.

자주 사용하는 Signal

자주 사용되는 signal로는 다음과 같은 것들이 있다.

  • HUP, INT, KILL, STOP, CONT, 0 이 중 0은 조금 특별하다.

Signal 0

0은 실제로 프로세스에 동작을 발생시키는 signal이 아니다. 그래서 null signal이라고 부르기도 한다. 주로 다음과 같은 용도로 사용된다.

  • 해당 프로세스가 존재하는지 확인

  • 현재 사용자가 그 프로세스에 signal을 보낼 권한(permission)이 있는지 확인

즉 signal 자체로 어떤 동작을 수행시키는 것이 아니라, 프로세스 상태를 검사하기 위한 용도로 사용된다.


PID -1

일반적으로 PID는 0 이상의 양수로 생각하기 쉽지만, kill에서는 음수 값도 특별한 의미로 사용된다. 예를 들어, kill -1 은 단순히 PID가 -1인 프로세스를 의미하는 것이 아니다. 이는 현재 프로세스 자신과 init 프로세스(PID 1)를 제외한 모든 프로세스에 signal을 보내라는 의미이다. 즉, 자기 자신 제외, PID 1 제외, 나머지 전체 프로세스 대상 이라는 특별한 동작을 수행하게 된다.

음수 PID와 PGID

-1 이외의 다른 음수 값은 PGID(Process Group ID)를 의미한다. kill -100 이라고 입력하면, PID 100 프로세스 하나에 signal을 보내는 것이 아니라 PGID가 100인 프로세스 그룹 전체 에게 signal을 보내게 된다.

즉 일반적인 kill PID는 하나의 프로세스를 대상으로 하지만, 음수 값을 사용하면 특정 프로세스 그룹 전체에 signal을 전달할 수 있다. 이러한 프로세스 그룹 정보는 ps j 명령어를 통해 확인할 수 있다.

결국 지금까지의 흐름은:

  1. ps(process status)로 프로세스 상태를 확인하고

  2. PID(Process ID)PGID(Process Group ID)를 파악한 뒤

  3. kill을 사용해 원하는 signal을 전달한다 는 구조로 이해할 수 있다.


2️⃣ Resources

리눅스 자원: CPU 정보 확인 (lscpu)

리눅스에서 현재 사용 중인 CPU 정보(CPU Information)lscpu 명령어로 확인할 수 있다. 이 명령어를 실행하면 CPU 코어 수, 제조사 정보, CPU 기능, 소켓 구성, NUMA 정보 등을 볼 수 있다.

예를 들어 lscpu 결과에서 코어가 4개로 표시된다면, 해당 시스템에서 사용할 수 있는 CPU 자원이 4개라는 의미로 볼 수 있다. 다만 실제 물리 코어 수인지, 논리 CPU 수인지는 CPU(s), Core(s) per socket, Thread(s) per core 항목을 함께 확인해야 한다.

Vendor ID는 CPU 제조사를 나타낸다. 일반적으로 Intel이나 AMD가 표시되며, Apple 하드웨어에서 리눅스를 사용하는 경우 Apple 관련 정보가 나타날 수도 있다. Apple 장비에서도 리눅스를 설치하거나 실행하는 것은 가능하다.

Flags 항목에는 현재 CPU가 지원하는 기능들이 표시된다. 이 값들은 CPU가 어떤 명령어나 기능을 제공하는지 보여주는 정보다.

또한 NUMA node(s) 항목도 확인할 수 있다. NUMA(Non-Uniform Memory Access) 는 CPU와 메모리 접근 구조와 관련된 정보다. 일반적인 개인용 컴퓨터에서는 보통 NUMA node(s): 1로 표시된다. 이는 하나의 NUMA 노드만 있다는 뜻이다.

다만 NUMA node(s): 1이 곧바로 CPU 소켓이 1개라는 뜻은 아니다. CPU 소켓 수는 Socket(s) 항목에서 확인하는 것이 정확하다. 일반적인 컴퓨터는 소켓이 하나인 경우가 많지만, 서버용 메인보드에서는 CPU 소켓이 2개, 4개, 8개처럼 여러 개 들어갈 수도 있다.

정리하면, lscpu는 리눅스에서 CPU 자원을 확인할 때 사용하는 기본 명령어이며, CPU 코어 수, 제조사, 기능, 소켓 수, NUMA 구성 등을 확인할 수 있다.


리눅스 자원: CPU 정보 확인 (Linux Resources: Checking CPU Information) - lstopo, htop, top

lstopo는 시스템의 위상 정보(System Topology) 를 보여주는 명령어이다. 앞에서 살펴본 lscpu가 CPU 코어 수나 기본적인 CPU 정보를 보여준다면, lstopo는 시스템 내부 구조를 더 세부적으로 보여준다. 예를 들어 CPU 코어뿐만 아니라 Cache 정보, L2 Cache, PCI Bus 위치 등도 확인할 수 있다.

컴퓨터를 직접 조립하거나 서버를 구축하지 않더라도, 시스템이 어떤 하드웨어 구조를 가지고 있는지 확인해야 할 때가 있다. 이때 lstopo를 사용하면 컴퓨터를 직접 열어보지 않아도 CPU, Cache, PCI Bus 등 자원이 어떤 구조로 연결되어 있는지 확인할 수 있다. 이렇게 확인한 정보는 시스템 자원 분석이나 성능 최적화에 활용할 수 있다.

htop은 현재 시스템 자원 사용 상태를 실시간으로 확인할 수 있는 명령어이다. 앞에서 배운 ps 명령어는 실행한 순간의 프로세스 정보만 보여준다. 반면 htop은 CPU와 Memory 사용량을 계속 갱신하면서 보여주기 때문에 시스템 상태를 모니터링하기에 편리하다.

htop은 다음과 같이 설치할 수 있다.

sudo apt install htop

또는 환경에 따라 다음 명령어로 설치할 수도 있다.

sudo snap install htop

htop을 실행하면 CPU 사용량을 코어별로 확인할 수 있고, Memory가 얼마나 사용되고 있는지도 볼 수 있다. 비슷한 기능은 top 명령어로도 확인할 수 있다.

화면에는 PID, USER, PRI, NI, VIRT 같은 값들이 표시된다. 이 항목들은 앞에서 배운 ps 명령어에서 확인할 수 있는 프로세스 정보와 관련된 값들이다. 사용자는 이 값들을 보고 현재 시스템이 어떤 상태인지 판단할 수 있다.

마지막 부분의 COMMAND 항목을 보면 해당 프로세스가 어떤 명령어로 실행되었는지 확인할 수 있다. 이를 통해 현재 시스템에서 어떤 프로그램이 실행 중인지, 사용자가 어떤 작업을 하고 있는지 파악할 수 있다.


Linux Resources: CPU Affinity (taskset, numactl)

CPU 자원은 기본적으로 운영체제의 스케줄러(Scheduler) 가 알아서 관리한다. 사용자가 직접 개입하지 않아도 프로세스가 어느 CPU 코어에서 실행될지 자동으로 결정되도록 설계되어 있다. 이는 사람의 개입을 최소화하고, 시스템이 자원을 효율적으로 사용할 수 있도록 하기 위한 방식이다.

하지만 특정 프로세스를 특정 CPU 코어에서만 실행되도록 지정하고 싶을 때가 있다. 이때 사용하는 명령어가 taskset이다. taskset은 프로세스의 CPU Affinity 를 설정하는 명령어로, 어떤 프로세스를 어느 CPU 코어에서 실행할지 지정할 수 있다.

예를 들어 my_program을 1번 CPU에서 실행하도록 지정하려면 다음과 같이 사용할 수 있다.

taskset -c 1 my_program

여러 CPU 코어를 지정할 수도 있다. 예를 들어 6번부터 9번 CPU까지 사용하게 하려면 다음과 같이 입력한다.

taskset -c 6-9 my_program

또는 3번, 5번, 7번 CPU처럼 특정 코어만 골라 지정할 수도 있다.

taskset -c 3,5,7 my_program

과거의 단순한 컴퓨터 환경에서는 작업이 순서대로 대기하고, CPU가 비면 다음 작업을 실행하는 전통적인 스케줄링(Scheduling) 방식이 주로 사용되었다. 하지만 멀티코어 CPU 환경에서는 여러 코어를 활용해야 하므로 더 복잡한 스케줄링 방식이 사용된다. taskset을 사용하면 이런 환경에서도 특정 프로세스가 특정 코어에서만 스케줄링되도록 제한할 수 있다.

numactl은 프로세스나 공유 메모리의 NUMA 정책(NUMA Policy) 을 제어하는 명령어이다. taskset이 주로 CPU 코어를 지정하는 데 사용된다면, numactl은 프로세스가 어떤 CPU 노드와 어떤 NUMA 메모리를 사용할지 지정할 수 있다.

고성능 시스템에서는 CPU 코어 수가 많아지고, 메모리도 여러 영역으로 나뉘어 CPU와 연결된다. 이때 CPU와 물리적으로 가까운 메모리를 사용하는 것이 성능에 유리할 수 있다. numactl은 이런 구조에서 CPU와 메모리 자원을 좀 더 직접적으로 관리할 수 있게 해준다.

예를 들어 my_program을 0번 NUMA 노드의 CPU와 0번 NUMA 노드의 메모리에 묶으려면 다음과 같이 사용할 수 있다.

numactl --cpunodebind=0 --membind=0 my_program

이 명령은 프로그램이 0번 NUMA 노드의 CPU를 사용하고, 메모리도 0번 NUMA 노드의 메모리를 사용하도록 지정한다.

반면 my_program을 0번 CPU에만 묶고, 메모리 위치는 따로 지정하지 않으려면 다음과 같이 사용할 수 있다.

numactl --physcpubind=0 my_program

이 경우 CPU는 0번 CPU로 지정하지만, 메모리 사용 위치까지 강제하지는 않는다. 즉, CPU만 신경 쓰고 메모리는 운영체제의 기본 정책에 맡기는 방식이다.

정리하면, taskset은 프로세스를 특정 CPU 코어에서 실행되도록 지정하는 명령어이고, numactl은 CPU뿐만 아니라 NUMA 메모리 정책까지 함께 제어할 수 있는 명령어이다. 일반적인 환경에서는 운영체제가 CPU 자원을 자동으로 관리하지만, 고성능 시스템이나 세밀한 성능 조정이 필요한 환경에서는 이런 명령어를 통해 자원을 직접 관리할 수 있다.


Linux Resources: Priority Adjustment (nice)

리눅스에서는 프로세스의 스케줄링 우선순위(Scheduling Priority) 를 조정할 수 있다. 이때 사용하는 대표적인 명령어가 nice이다. nice는 새로 실행하는 프로세스의 Nice 값(Nice Value) 을 지정해서, 해당 프로세스가 CPU 자원을 얼마나 우선적으로 사용할지에 영향을 준다.

리눅스의 Nice 값은 일반적으로 -20부터 19까지 설정할 수 있다. 숫자가 낮을수록 우선순위가 높고, 숫자가 높을수록 우선순위가 낮다. 즉, -20에 가까울수록 더 먼저 처리될 가능성이 높고, 19에 가까울수록 상대적으로 뒤로 밀리게 된다.

다만 모든 사용자가 마음대로 우선순위를 높일 수 있는 것은 아니다. 일반 사용자(User)는 보통 Nice 값을 높여서 우선순위를 낮추는 것은 가능하지만, Nice 값을 음수로 낮춰 우선순위를 높이려면 root 권한(Superuser Privilege) 이 필요하다.

nice 명령어를 사용하지 않고 일반적으로 실행한 새 프로세스의 기본 Nice 값은 0이다. 하지만 nice 명령어를 사용하면서 -n 옵션으로 값을 지정하지 않으면, 기본적으로 Nice 값이 10 증가한다. 즉, 그냥 실행하면 Nice 값이 0이지만, nice my_program처럼 실행하면 Nice 값이 10이 되어 우선순위가 낮아진다. 이는 “빨리 처리해 주세요”가 아니라 “다른 작업보다 조금 늦게 처리해도 됩니다”라는 의미에 가깝다.

예를 들어 my_program의 Nice 값을 15로 지정해서 실행하려면 다음과 같이 입력한다.

nice -n 15 my_program

현재 실행 중인 프로세스의 Nice 값은 top, htop, ps -l 같은 명령어로 확인할 수 있다. 이러한 도구를 통해 프로세스별 우선순위를 확인하고, 시스템에서 어떤 작업이 더 높은 우선순위로 실행되고 있는지 파악할 수 있다.

정리하면, nice는 새 프로세스의 CPU 스케줄링 우선순위를 조정하는 명령어이다. 기본 Nice 값은 0이며, 값이 낮을수록 우선순위가 높고 값이 높을수록 우선순위가 낮다. 특히 음수 Nice 값을 설정해 우선순위를 높이려면 root 권한이 필요하다.


Linux Resources: Priority Adjustment (renice)

renice는 이미 실행 중인 프로세스의 스케줄링 우선순위(Scheduling Priority) 를 변경할 때 사용하는 명령어이다. 앞에서 본 nice가 새로 실행하는 프로세스의 우선순위를 지정하는 명령어라면, renice는 현재 실행 중인 프로세스의 Nice 값(Nice Value) 을 바꾸는 데 사용된다.

리눅스에서 Nice 값은 일반적으로 -20부터 19까지 설정할 수 있다. 숫자가 낮을수록 우선순위가 높고, 숫자가 높을수록 우선순위가 낮다. 즉, -20에 가까울수록 CPU 자원을 더 우선적으로 받을 가능성이 높고, 19에 가까울수록 상대적으로 뒤로 밀리게 된다.

renice는 특정 프로세스 ID(Process ID, PID) 를 대상으로 사용할 수 있다. 예를 들어 PID가 1234인 프로세스의 Nice 값을 10으로 변경하려면 다음과 같이 입력한다.

renice 10 1234

이 경우 별도의 옵션을 지정하지 않으면 1234는 기본적으로 프로세스 ID로 해석된다.


Keep Running After Logout: Ignoring SIGHUP with nohup

리눅스를 사용하다 보면 터미널을 종료하거나 원격 접속이 끊긴 뒤에도 프로그램을 계속 실행해야 할 때가 있다. 이때 사용할 수 있는 명령어가 nohup이다.

터미널 세션(Session)이 종료되거나 연결이 끊기면 실행 중인 프로세스에 SIGHUP(Signal Hang Up) 시그널이 전달될 수 있다. 일반적으로 이 시그널을 받은 프로세스는 종료된다.

nohup은 이 SIGHUP 시그널을 무시하도록 만들어, 터미널이 종료된 뒤에도 프로세스가 계속 실행될 수 있게 한다.

예를 들어 my_program을 로그아웃 이후에도 계속 실행하고 싶다면 다음과 같이 사용할 수 있다.

nohup my_program &

여기서 &는 프로그램을 백그라운드(Background) 에서 실행하겠다는 의미이다. nohup으로 실행한 프로그램의 출력은 기본적으로 nohup.out 파일에 저장된다.

정리하면, nohup은 터미널 종료나 접속 종료 이후에도 프로세스를 계속 실행하고 싶을 때 사용하는 명령어이다. 핵심은 SIGHUP 시그널을 무시하게 만들어, 실행 중인 작업이 중간에 끊기지 않도록 하는 것이다.


Keep Running After Logout: screen

리눅스/유닉스에서 로그아웃 후에도 작업을 계속 실행해야 할 때 screen 명령어를 사용할 수 있다. screenVT100/ANSI 가상 터미널(Virtual Terminal) 을 만들어주는 프로그램이다.

일반적으로 사용자가 로그인하면 하나의 터미널 창에서 작업을 하게 된다. 이때 screen 명령을 실행하면 기존 터미널 안에 새로운 가상 터미널 세션(Session)이 만들어진다. 이 세션 안에서 명령어를 실행하거나 프로그램을 돌릴 수 있고, 필요하면 화면에서 빠져나온 뒤 나중에 다시 해당 세션으로 돌아갈 수 있다.

screen의 핵심은 터미널 창을 닫거나 로그아웃하더라도, 그 안에서 실행 중이던 프로세스(Process)가 계속 유지될 수 있다는 점이다. 사용자는 원격 접속을 종료한 뒤에도 나중에 다시 로그인해서 기존 screen 세션에 접속하고, 이전 작업 상태를 이어서 확인할 수 있다.

예를 들어 원격 서버에 접속해서 오래 걸리는 작업을 실행해야 하는 상황을 생각할 수 있다. 단순히 터미널에서 작업을 실행한 뒤 접속을 끊으면 작업이 중단될 수 있다. 하지만 screen 안에서 작업을 실행하면 로그아웃한 뒤에도 작업이 계속 돌아가며, 이후 다른 장소에서 다시 접속해 상태를 확인할 수 있다.

예를 들어 screen을 시작하려면 다음과 같이 입력한다.

screen

screen 안에서 작업을 실행한 뒤 세션에서 빠져나오면 원래 터미널로 돌아올 수 있다. 이후 다시 접속해서 기존 세션을 불러오면 작업 중이던 화면을 이어서 볼 수 있다.

정리하면, screen은 로그아웃 후에도 작업을 유지하기 위해 사용하는 가상 터미널 도구이다. 원격 접속 환경에서 오래 걸리는 작업을 실행하거나, 장소를 옮겨가며 같은 작업 상태를 이어서 확인해야 할 때 유용하다.


Keep Running After Logout: tmux

리눅스/유닉스에서 로그아웃 후에도 작업을 계속 유지하고 싶을 때 tmux를 사용할 수 있다. tmux는 터미널 세션을 관리해주는 터미널 멀티플렉서(Terminal Multiplexer) 이다.

tmux는 앞에서 본 screen과 비슷하게 터미널 로그인이나 로그아웃 상태와 상관없이 작업을 유지할 수 있게 해준다. 사용자는 tmux 세션 안에서 프로그램을 실행하고, 터미널 연결을 끊은 뒤에도 나중에 다시 접속해 같은 작업 상태를 이어서 확인할 수 있다.

tmux의 특징은 하나의 터미널 안에서 여러 개의 창(Window)을 만들거나, 화면을 여러 영역으로 나누는 분할(Pane Split) 기능을 제공한다는 점이다. 그래서 하나의 SSH 접속 환경에서도 여러 작업을 동시에 관리하기 좋다.

예를 들어 한쪽 화면에서는 로그를 확인하고, 다른 화면에서는 명령어를 실행하거나 서버 상태를 모니터링할 수 있다. 이런 점 때문에 tmuxSSH 원격 접속(SSH Remote Access) 으로 서버 작업을 할 때 유용하게 사용된다.

tmux는 다음 명령어로 설치할 수 있다.

sudo apt install tmux

설치 후에는 다음과 같이 실행할 수 있다.

tmux

정리하면, tmux는 로그아웃 후에도 작업을 유지할 수 있게 해주는 터미널 세션 관리 도구이다. screen과 비슷하지만, 창과 화면 분할 기능이 강력해 원격 서버에서 여러 작업을 동시에 수행할 때 특히 유용하다.

리눅스에 tmux를 치니 창이 새로 뜨는것을 확인할 수 있었다.