Processes
Process Management Activities
- The operating system is responsible for the following activities in connection with process management:
- Creating and deleting both user and system processes
- Suspending and resuming processes
- Providing mechanisms for process synchronization
- Providing mechanisms for process communication
- Providing mechanisms for deadlock handling
- 운영 체제는 프로세스 관리와 관련하여 다음과 같은 활동을 담당한다.
- 사용자 및 시스템 프로세스 생성 및 삭제
- 프로세스 일시 중단 및 재개
- 프로세스 동기화를 위한 메커니즘 제공
- 프로세스 통신을 위한 메커니즘 제공
- 교착 상태 처리를 위한 메커니즘 제공
운영체제 프로세스 관리
1) 사용자 및 시스템 프로세스 생성 및 삭제
2) 프로세스 일시 중단 및 재개
3) 동기화 메커니즘
4) 통신 메커니즘
5) 교착 상태 처리 메커니즘
Process: What is it?
- A running program (= A program currently in execution)
- An active entity, with a program counter(PC) specifying the next
instruction to be executed and a set of associated resources
- A program is a passive entity, like the contents of a file stored on a disk
- 실행 중인 프로그램(= 현재 실행 중인 프로그램)
- 다음을 지정하는 프로그램 카운터(PC)가 있는 활성 엔티티 그리고 실행할 명령 및 관련 리소스 집합
- 프로그램은 디스크에 저장된 파일의 내용과 같이 수동적인 엔터티이다.
프로세스: 실행 중인 프로그램. PC (Program Counter)가 있는 활성 엔티티, 명령/리소스 집합. 프로그램은 수동 엔티티.
The Memory Layout of a Process
- Typically divided into multiple sections:
- “Text Section” containing the executable code
- “Data Section” containing global variables
-> These two sections’ sizes are fixed, as their sizes do
not change during program run time!
-> However, the following two sections can shrink andgrow dynamically during program execution. OS must
ensure they do not overlap one another!!
- Stack Section & Heap Section
- 일반적으로 여러 섹션으로 나뉜다.
- executable code를 포함하는 "텍스트 섹션"
- global variables를 포함하는 "데이터 섹션"
- -> 이 두 섹션의 크기는 크기가 고정되어 있다. 프로그램 실행 시간 동안 변경되지 않는다!
- -> 단, 다음 두 부분은 축소될 수 있으며 프로그램 실행 중에 동적으로 증가한다. OS는 필수이다. 그들이 서로 겹치지 않도록 해라!!
- 스택 섹션 및 힙 섹션
프로세스의 메모리는 multiple sectoin으로 나뉜다.
text section: executable code, 크기 고정
data section: global variables, 크기 고정
stack & heap: 동적 축소, 증가.
- Typically divided into multiple sections:
- “Stack Section” containing temporary data storage when invoking functions
- Each time a function is called, an activation record containing function parameters, local variables, and the return address is pushed onto the stack;
- When control is returned from the function, the activation record is popped from the stack
- “Heap Section” will grow as memory is dynamically allocated (i.e., created at runtime by malloc), and will
shrink when memory is returned to the system
- 일반적으로 여러 섹션으로 나뉜다.
- 함수를 호출할 때 임시 데이터 저장소를 포함하는 "Stack Section"
- 함수가 호출될 때마다 함수 매개 변수, 로컬 변수 및 반환 주소가 포함된 활성화 레코드가 스택에 푸쉬된다.
- 기능에서 제어가 반환되면 활성화 레코드가 스택에서 팝업된다.
- "Heap Section"은 메모리가 동적으로 할당될 때(즉, malloc에 의해 런타임에 생성됨) 증가하고 메모리가 시스템으로 반환될 때 축소된다.
stack section: 함수가 호출될 때 임시 데이터 저장소. activation record push (제어가 반환되면 popup)
heap section: 메모리 동적 할당 (malloc)
User Space VS. Kernel Space Memory
- Kernel space
- Memory region that stores all code and data related to OS kernel
- Any user process cannot access the kernel space, otherwise resulting in a segmentation fault
- All user processes share the same kernel space region
- 커널 공간
- OS 커널과 관련된 모든 코드 및 데이터를 저장하는 메모리 영역
- 사용자 프로세스는 커널 공간에 액세스할 수 없다. 그렇지 않으면 분할 오류가 발생한다.
- 모든 사용자 프로세스가 동일한 커널 공간 영역을 공유한다.
kernel space. 사용자 프로세스는 액세스 불가능. 모든 사용자 프로세스는 동일한 kernel space region 공유.
Memory Layout of a C Program
Program versus Process
- A program by itself is not a process; It becomes a process when an executable file is loaded into memory
- Two common techniques for program execution: double-clicking an icon (=the executable file) and typing command line for the executable file’s name
- Although several processes may be associated with the same program, they are nevertheless considered separate execution sequences
- Text sections are equivalent, but the data/heap/stack sections vary.
- 프로그램 자체는 프로세스가 아니다. 실행 파일이 메모리에 로드될 때 프로세스가 된다.
- 프로그램 실행을 위한 두 가지 일반적인 기술: 아이콘(=실행 파일)을 두 번 클릭하고 실행 파일 이름에 명령줄을 입력한다.
- 여러 프로세스가 동일한 프로그램과 연관될 수 있지만 그럼에도 불구하고 별도의 실행 시퀀스로 간주된다.
- text 섹션은 동일하지만 data/heap/stack 섹션은 다르다.
실행 파일이 메모리에 로드될 때 프로세스가 된다. 여러 프로세스가 동일한 프로그램을 실행할 수 있고 별도의 실행 시퀀스로 간주. text만 동일.
Process State
- As a process executes, it changes “state”, and the state may be in one of the followings:
- New: The process is being created
- Ready: The process is waiting to be assigned to a processor
- Running: Instructions are being executed -> Only one process can be running on any processor core at any instant; Many processes may be ready and waiting states
- Waiting: The process is waiting for some event to occur (such as I/O
completion or reception of a signal)
- Terminated: The process has finished execution
- 프로세스가 실행됨에 따라 상태가 변경되며 상태는 다음 중 하나가 될 수 있다.
- New: 프로세스가 생성되는 중이다.
- Ready: 프로세스가 프로세서에 할당될 때까지 대기 중이다.
- Running: 명령이 실행되고 있다 -> 프로세서 코어에서 한 번에 하나의 프로세스만 실행할 수 있다. 많은 프로세스가 준비 및 대기 상태일 수 있다.
- Waiting: 프로세스가 일부 이벤트(예: I/O 신호의 완료 또는 수신)가 발생하기를 기다리는 중이다.
- Terminated: 프로세스 실행이 완료되었다.
Process State의 변화를 아는 것이 중요하다. transaction diagram의 의미를 잘 기억해두어야 한다.
(외우기)
Process Representation
- Each process is represented in the OS by “Process Control Block (PCB),” also called a Task Control Block
- In brief, it serves as the repository for all the data needed to start, or restart, a process, along with some accounting data
- Thus, it contains many pieces of information associated with a specific process
- 각 프로세스는 OS에서 "프로세스 제어 블록(PCB)"으로 표시되며, 이는 태스크 제어 블록이라고도 한다.
- 간단히 말해서, 프로세스를 시작하거나 재시작하는 데 필요한 모든 데이터와 일부 회계 데이터의 저장소 역할을 한다.
- 따라서 특정 프로세스와 관련된 많은 정보를 포함한다.
프로세스는 PCB로 표시된다.
Process Control Block (PCB)
- Process state
- Program counter: the address of the next instruction to be executed for this process
- CPU Registers: Contents of all process-centric registers
- CPU Scheduling information: process priorities, scheduling queue pointers, and any other scheduling parameters
- Memory Management information: memory allocated to the process
- Accounting info: The amount of CPU used, clock time elapsed since start, time limits, and so on
- I/O status information: The list of I/O devices allocated to process, a list of open files, and so on
- Process state
- Program counter: 이 프로세스에 대해 실행할 다음 명령의 주소
- CPU Registers: 모든 프로세스 중심 레지스터의 내용
- CPU Scheduling information: 프로세스 우선 순위, 스케줄링 대기열 포인터 및 기타 스케줄링 매개 변수
- Memory Management information: 프로세스에 할당된 메모리
- Accounting info: 사용된 CPU 양, 시작 후 경과된 클럭 시간, 제한 시간 등
- I/O state information: 프로세스에 할당된 I/O 장치 목록, 열려 있는 파일 목록 등
PCB 구성 요소 (외우기)
Process Representation in Linux
ps
- Most operating systems have system programs that allow the user to look at the current process list
- On Unix/Linux systems, one can run the ps program
- 대부분의 운영 체제에는 사용자가 현재 프로세스 목록을 볼 수 있는 시스템 프로그램이 있다.
- 유닉스/리눅스 시스템에서 ps 프로그램을 실행할 수 있다.
ps 명령어 : 현재 프로세스 목록 확인
- ps /* Report a snapshot of the current processes */
- ps –el /* To show complete information for all processes currently active in the system */
- ps –ef /* To show all processes or threads running on the system */
- ps /* 현재 프로세스의 스냅샷 보고*/
- ps –el /* 시스템에서 현재 활성화된 모든 프로세스에 대한 전체 정보 표시*/
- ps –ef /* 시스템에서 실행 중인 모든 프로세스 또는 스레드를 표시 */
Process Scheduling
- The objective of multiprogramming is to have some process running at all times so as to maximize CPU utilization
- The objective of time sharing is to switch a CPU core among processes so frequently that users can interact with each program while it is running
- To meet these objectives, the process scheduler selects an available process (possibly from a set of several available processes) for program execution on a core
- Interrupts cause the OS to change CPU core from its current task and to run a kernel routine. When an interrupt occurs, the system needs to save the current context of the process running on the CPU core
- 멀티프로그래밍의 목적은 CPU 활용률을 극대화하기 위해 일부 프로세스를 항상 실행하는 것이다.
- 시간 공유의 목적은 CPU 코어를 프로세스 간에 너무 자주 전환하여 사용자가 실행 중인 각 프로그램과 상호 작용할 수 있도록 하는 것이다.
- 이러한 목표를 달성하기 위해 프로세스 스케줄러는 코어에서 프로그램을 실행하기 위해 사용 가능한 프로세스를 선택한다.
- 인터럽트로 인해 OS가 CPU 코어를 현재 작업에서 변경하고 커널 루틴을 실행한다. 인터럽트가 발생하면 시스템은 CPU 코어에서 실행 중인 프로세스의 현재 컨텍스트를 저장해야 한다.
멀티프로그래밍 목적: CPU 활용률을 극대화하기 위해 일부 프로세스를 항상 실행
시간 공유 목적: CPU 코어를 프로세스 간 자주 전환. 사용자 상호 작용.
process scheduler: 사용 가능한 프로세스 선택
interrupt로 CPU core 변경: 프로세스 context 저장
Context Switch
- The context is represented in the PCB of the process. It includes the value of the CPU registers, the process state, and memory management information.
- When CPU switches to another process, the system must save the state of the old process and load the saved state for the new process via a context switch!
- Context-switch time is overhead, because the system does no useful work while switching
- Switching speed varies from machine to machine, depending on h/w support
- 컨텍스트는 프로세스의 PCB에 표시된다. 여기에는 CPU 레지스터의 값, 프로세스 상태 및 메모리 관리 정보가 포함된다.
- CPU가 다른 프로세스로 전환되면 시스템은 이전 프로세스의 상태를 저장하고 컨텍스트 스위치를 통해 새 프로세스의 저장된 상태를 로드해야 한다!
- 전환하는 동안 시스템이 유용하게 작동하지 않기 때문에 컨텍스트 전환 시간이 오버헤드된다.
- 전환 속도는 하드웨어 지원에 따라 기계마다 다르다.
context PCB에 표시
context switch: 새 프로세스 저장된 상태 로드
Diagram showing Context Switch from Process to Process
Operations on Processes
- Process creation
- Parent process create children processes, which may in turn create other processes, forming a tree of processes
- Process is identified and managed via a process identifier (pid), which is typically an integer value
- The init process serves as the root parent process for all user processes
[ init has been replaced with the systemd process in recent distributions of Linux ]
- 프로세스 생성
- 상위 프로세스는 하위 프로세스를 생성하고, 하위 프로세스는 다른 프로세스를 생성하여 프로세스 트리를 형성할 수 있다.
- 프로세스는 일반적으로 정수 값인 프로세스 식별자(pid)를 통해 식별 및 관리된다.
- 초기화 프로세스는 모든 사용자 프로세스의 루트 상위 프로세스 역할을 한다.
[init는 리눅스의 최근 배포판에서 systemd 프로세스로 대체되었다.]
프로세스 생성 : 트리 형성
pid로 관리
init process는 모든 사용자 프로세스의 root parent process
Processes Tree with 'systemd' process as the root of all user-level processes
- pstree command on RaspberryPi
Operations on Processes
- Process creation
- In general, when a process creates a child process, that child process will need certain resources (CPU time, memory, files, I/O devices) to accomplish its task
- 1) A child process may be able to obtain its resources directly from OS, or 2) it may be constrained to a subset of the resources of the parent process.
- For 2), the parent may have to partition its resources among its children, or it may be able to share some resources (such as memory or files) among several of its children
» Restricting a child process to a subset of the parent’s resources prevents any process from overloading the system by creating too many child processes
- 프로세스 생성
- 일반적으로 프로세스가 하위 프로세스를 생성할 때 해당 하위 프로세스는 작업을 수행하기 위해 특정 리소스(CPU 시간, 메모리, 파일, I/O 장치)가 필요하다.
- 1) 하위 프로세스는 OS에서 직접 리소스를 가져올 수도 있고, 2) 상위 프로세스의 리소스 하위 집합으로 제한될 수도 있다.
- 2)의 경우, 부모는 리소스를 자식 간에 분할해야 하거나 일부 리소스(예: 메모리 또는 파일)를 자식 간에 공유할 수 있다.
» 하위 프로세스를 상위 리소스의 하위 집합으로 제한하면 하위 프로세스가 너무 많이 생성되어 시스템에 과부하가 걸리지 않는다.
프로세스 생성: 특정 리소스 필요.
1) OS에서 가져오기 / 2) 상위 프로세스의 리소스 하위 집합
2)의 경우 리소스 자식 간 분할 혹은 자식 간 공유. 하위 집합으로 제한하면 과부화가 걸리지 않는다.
fork()
- The fork()system call creates a new process identical to the calling one (= a clone of the currently running program)
- The new process consists of a copy of the address space of the original process
- Both processes (the parent and the child) continue execution at the next line of code after the fork(), with one difference: the return code!
- 포크 시스템 호출은 호출하는 프로세스와 동일한 새 프로세스를 생성한다.(= 현재 실행 중인 프로그램의 클론).
- 새 프로세스는 원래 프로세스의 주소 공간 복사본으로 구성된다.
- 두 프로세스(부모와 자식) 모두 포크() 다음 코드 행에서 실행을 계속하지만, 한 가지 차이점은 반환 코드이다!
포크 = 복제. 부모와 자식은 반환 코드가 다르다.
This program calls the fork() function and then goes into an infinite loop
Assuming the program is stored in a file named fork1.c, then it can be executed as follows:
아래 프로그램은 포크() 함수를 호출한 다음 무한 루프로 이동한다.
프로그램이 fork1.c라는 이름의 파일에 저장되어 있다고 가정하면 다음과 같이 실행할 수 있다.
Return Code for the fork()
- Return value for the fork() differs…
- Zero for the new (“Child”) process
- Process ID of the child process for the “Parent” process
- The figure below displays a timeline of events during a fork system call
- 포크()의 반환 값이 다르다.
- 새("자식") 프로세스에 대한 0
- 상위 프로세스에 대한 하위 프로세스의 프로세스 ID
- 아래 그림은 포크 시스템 호출 중 이벤트의 타임라인을 표시한다.
return code가 다르다. (더 살펴보기)
Example of fork()
- The return value from fork() allows a program to affect which code its clone will execute
- fork()의 반환 값을 사용하면 프로그램이 클론이 실행할 코드에 영향을 줄 수 있다.
- Here, the parent and child processes will each go into different code blocks. Each process has its own variables, and they are executing different codes
- The order of the lines of output will vary from run to run. This is because after fork(), both processes are running concurrently and the order of execution is not predictable
- 여기서 부모 및 자식 프로세스는 각각 다른 코드 블록으로 들어갑니다. 각 프로세스에는 고유한 변수가 있으며 서로 다른 코드를 실행하고 있다.
- 출력 라인의 순서는 실행마다 다르다. 포크() 이후 두 프로세스가 동시에 실행되고 실행 순서를 예측할 수 없기 때문이다.
Using fork() in a nested fashion
- The fork() function can be called iteratively, meaning that one process can start up multiple new processes, which can in turn start multiple new processes, and so on
- 포크() 함수는 반복적으로 호출될 수 있으며, 이는 한 프로세스가 여러 개의 새 프로세스를 시작할 수 있음을 의미한다.
- The getpid() function is a system call that returns the PID of the current process
- This program calls fork(), creating a clone. Then each of those programs calls fork(), creating another clone each
- getpid() 함수는 현재 프로세스의 PID를 반환하는 시스템 호출이다.
- 이 프로그램은 포크()를 호출하여 복제본을 생성합니다. 그런 다음 각 프로그램은 포크()를 호출하여 각각 다른 클론을 만든다.
exec() family
- After a fork() system call, one of the two processes typically uses the exec() family of system calls to replace the process’s memory space with a new program
- The process retains its PID but otherwise becomes a new program
- Several variations in the exec() family of functions, including execl(), execlp(), exece(), execv(), and execvp()
- 포크() 시스템 호출 후, 두 프로세스 중 하나는 일반적으로 시스템 호출의 exec() 계열을 사용하여 프로세스의 메모리 공간을 새 프로그램으로 대체한다.
- 프로세스가 PID를 유지하지만 그렇지 않으면 새 프로그램이 된다.
- execl(), execlp(), exec(), execv() 및 execvp()를 비롯한 exec() 기능군의 여러 변형
- This program outputs the line “Ready to exec() …” and after calling execvp(), replaces its code with the date program
- Note that the line “… did it work” is not displayed,because at that point the code has been replaced.Instead, we see the output of executing “date –u”
- 이 프로그램은 "Ready to exec() …" 행을 출력하고 execvp()를 호출한 후 해당 코드를 날짜 프로그램으로 바꾼다.
- 이 시점에서 코드가 교체되었기 때문에 "… 작동했습니까?"라는 줄은 표시되지 않습니다.대신 "date –u"를 실행한 결과를 확인할 수 있다.
코드 자세히 봐보기
wait()
- It suspends a process, waiting for a child process to finish
- Its return value is the PID of the child process
- 프로세스가 일시 중단되고 하위 프로세스가 완료될 때까지 기다린다.
- 반환 값은 하위 프로세스의 PID이다.
- Here, the wait() function is executed in the block reached by the parent process. This causes the parent process to pause until the child process has finished, at which time the parent process resumes execution
- Always produced in this order
- 여기서 wait() 함수는 상위 프로세스가 도달한 블록에서 실행된다. 이로 인해 하위 프로세스가 완료될 때까지 상위 프로세스가 일시 중지되고, 이 때 상위 프로세스가 실행을 다시 시작한다.
- 항상 이 순서로 생산됨
wait() 함수는 상위 프로세스가 도달한 블록에서 실행.
waitpid()
- The wait() system call pauses until any child process has completed
- The parent issuing wait() makes itself move off the wait queue until the termination of the child
- Fine-grained control over synchronization can be obtained using the waitpid() function, which can wait on a process with a specific PID, or can wait until a process terminates in a specific manner or with a specific condition
- 하위 프로세스가 완료될 때까지 wait() 시스템 호출이 일시 중지된다.
- wait()를 실행하는 부모는 자식이 종료될 때까지 대기열에서 스스로 이동한다.
- 동기화에 대한 세밀한 제어는 waitpid() 함수를 사용하여 얻을 수 있습니다. waitpid() 함수는 특정 PID를 사용하여 프로세스를 기다리거나 프로세스가 특정 방식으로 종료되거나 특정 조건을 사용하여 프로세스가 종료될 때까지 기다릴 수 있다.
waitpid() : 동기화 세밀한 제어. 프로세스를 기다리거나 종료될 때까지 기다림.
system()
- The system() function is a C standard library function that puts the fork(), exec(), and wait() functions together into a single convenient call
- system() 함수는 fork(), exec(), wait() 함수를 하나의 편리한 호출에 함께 넣는 C 표준 라이브러리 함수이다.
- This program prints out a “ready” message, and then uses system() to execute the date program
- 이 프로그램은 "ready" 메시지를 출력한 다음 system()을 사용하여 날짜 프로그램을 실행한다.
Process Termination
- A process terminates when it executes last statement and then asks the OS to delete it by using the exit() system call
- At that point, the process may return a status value (typically an integer) to its waiting parent process (via the wait() system call)
- All the resources of the process – including physical and virtual memory,
open files, and I/O buffers – are deallocated and reclaimed by the OS
- Parent may terminate the execution of children processes using the abort() system call. Some reasons for doing so:
- Child has exceeded allocated resources
- Task assigned to child is no longer required
- The parent is exiting, and the OS does not allow a child to continue if its parent terminates -> This phenomenon is referred to as “cascading termination” (All children, grandchildren, etc. are terminated)
- 프로세스는 마지막 문을 실행한 다음 exit() 시스템 호출을 사용하여 OS에 삭제를 요청할 때 종료된다.
- 이 시점에서 프로세스는 대기 중인 상위 프로세스에 상태 값(일반적으로 정수)을 반환할 수 있습니다(wait() 시스템 호출을 통해).
- 물리적 메모리와 가상 메모리를 포함한 프로세스의 모든 리소스, 열린 파일 및 I/O 버퍼 – 할당 해제 및 OS에 의해 회수된다.
- 부모는 abort() 시스템 호출을 사용하여 자식 프로세스의 실행을 종료할 수 있다. 그렇게 하는 몇 가지 이유:
- 자식이 할당된 리소스를 초과했다.
- 하위에 할당된 작업은 더 이상 필요하지 않다.
- 부모가 종료 중이며, 부모가 종료되면 OS에서 자녀의 계속을 허용하지 않습니다 -> 이 현상을 "cascading termination"라고 한다.(모든 자녀, 손자 등이 종료됨).
exit() 시스템 호출로 종료. OS에 의해 리소스 해제.
부모는 abort()로 자식 프로세스 종료 가능 : 자식이 할당된 리소스 초과, 하위 할당 작업 필요 없음, 부모 종료중
- The parent process may wait for termination of a child process by using the wait() system call.
- The call is passed a parameter that allows the parent to obtain the exit status of the child. And it also returns the pid of the terminated child
- Zombie process
- A process which is terminated but its parent has not called wait() yet
- The child’s execution result remains alive until being reclaimed
- Orphan process
- A process whose parent exited without calling wait()
- Some OSes initiate cascading termination not to leave orphans
- In UNIX and Linux, the init process adopts such an orphan process and it calls wait() periodically
- 상위 프로세스는 wait() 시스템 호출을 사용하여 하위 프로세스의 종료를 기다릴 수 있다.
- 호출은 부모가 자식의 종료 상태를 얻을 수 있는 매개 변수를 전달합니다. 그리고 그것은 또한 종료된 아이의 pid를 반환한다.
- 좀비 프로세스
- 종료되었지만 상위 프로세스가 아직 wait()를 호출하지 않았다.
- 자식 실행 결과는 회수될 때까지 활성 상태로 유지된다.
- 고아 프로세스
- 부모가 wait()를 호출하지 않고 종료한 프로세스
- 일부 OS는 고아를 떠나지 않기 위해 계단식 종료를 시작한다.
- 유닉스와 리눅스에서 init 프로세스는 이러한 고아 프로세스를 입양하고 주기적으로 wait()를 호출한다.
상위 프로세스는 wait()로 하위 프로세스의 종룔를 기다린다.
좀비 프로세스: 부모가 wait()를 호출 안함. 자식 활성
고아 프로세스: 부모가 wait() 호출 안하고 종료함.
Single-threaded & Multi-threaded Processes
- Thread
- A flow of execution with its own execution state (CPU registers & stack) within a process
- The traditional process model has implied that a process is a program that performs a single thread of execution
- This single thread of control allows the process to perform only one task at a time
- Most modern OS provide features enabling a process to have multiple threads of execution and thus to perform more than one task at a time
- Beneficial on multicore systems (that provide multiple CPUs), where multiple threads can run in parallel
- 스레드
- 프로세스 내에서 자체 실행 상태(CPU 레지스터 및 스택)가 있는 실행 흐름
- 전통적인 프로세스 모델은 프로세스가 단일 실행 스레드를 수행하는 프로그램임을 암시한다.
- 이 단일 제어 스레드를 통해 프로세스는 한 번에 하나의 작업만 수행할 수 있다.
- 대부분의 최신 OS는 프로세스가 여러 개의 실행 스레드를 가질 수 있도록 하는 기능을 제공하므로 한 번에 두 개 이상의 작업을 수행할 수 있다.
- 여러 스레드가 병렬로 실행될 수 있는 멀티코어 시스템(여러 CPU 제공)에 유용하다.
스레드: 프로세스 내에서 자체 실행 상태가 있는 실행 흐름.
프로세스가 단일 실행 스레드를 수행하는 프로그램
프로세스가 여러 실행 스레드를 가짐. 멀티 코어 시스템에 유용하다.
- A thread is a basic unit of CPU utilization; it comprises a thread ID, a program counter(PC), a register set, and a stack
- It shares with other threads belonging to the same process its code section, data section, and other operating-system resources, such as open files and signals
- 스레드는 CPU 사용률의 기본 단위이며 스레드 ID, 프로그램 카운터(PC), 레지스터 세트 및 스택으로 구성된다.
- 코드 섹션, 데이터 섹션 및 기타 운영 체제 리소스(예: 열린 파일 및 신호)를 동일한 프로세스에 속하는 다른 스레드와 공유한다.
스레드는 CPU 사용률의 기본 단위
Multithreaded Programming
- Most modern software applications are multithreaded
- Multiple tasks with the application can be implemented by separate threads
- E.g.) Multithreaded server architecture:
- 대부분의 최신 소프트웨어 애플리케이션은 멀티 스레드이다.
- 애플리케이션이 포함된 여러 작업을 별도의 스레드로 구현할 수 있다.
- 예) 멀티스레드 서버 아키텍처:
- Most OS kernels are also multithreaded
- During system boot time on Linux systems, several kernel threads are created. Each thread performs a specific task, such as managing devices, memory management, or interrupt handling
- The special kernel thread ‘kthreadd (with PID=2)’ serves as the parent of all other kernel-level threads
- 대부분의 OS 커널도 멀티스레드이다.
- 리눅스 시스템에서 시스템 부팅 시간 동안 여러 커널 스레드가 생성된다. 각 스레드는 장치 관리, 메모리 관리 또는 인터럽트 처리와 같은 특정 작업을 수행한다.
- 특수 커널 스레드 'kthreadd(PID=2)'는 다른 모든 커널 수준 스레드의 상위 역할을 한다.
OS 커널 멀티스레드. 특수 커널 스레드 kthreadd(PID=2)는 모든 커널 수준 스레드의 상위 역할
The Special “kthreadd” process as the root of all kernel-level threads
- What is ‘kthreadd’?
- Every time a thread is needed to be created in kernel space, kthreadd (PID=2) is invoked.
- Because one can't simply create kernel thread from userspace call, kthreadd is used.
- It has no relation to the init (PID=1) process.
Benefits of Multithreaded Programming
- Responsiveness
- It may allow continued execution if part of process is blocked, especially important for user interfaces
- Resource Sharing
- Threads share resources of process, easier than shared memory or message passing
- Economy
- Cheaper than process creation, thread switching lower overhead than context switching
- Scalability
- A process can take advantage of multiprocessor architectures
- 응답성
- 프로세스의 일부가 차단된 경우, 특히 사용자 인터페이스에서 중요한 경우 계속 실행할 수 있다.
- 리소스 공유
- 스레드는 공유 메모리 또는 메시지 전달보다 쉬운 프로세스 리소스를 공유한다.
- 경제
- 프로세스 생성보다 저렴하며, 스레드 스위칭은 컨텍스트 스위칭보다 오버헤드가 낮다.
- 확장성
- 프로세스는 멀티프로세서 아키텍처를 활용할 수 있다.
프로세스 일부 차단된 경우 계속 실행 가능
프로세스 리소스 공유
스레드 스위칭은 오버헤드 낮다.
멀티프로세서 아키텍처 활용 가능
Multi-threading Model
- Support for threads may be provided either at the user level, for user threads, or by the kernel, for kernel threads
- User threads: management done by user-level threads library
- Kernel threads: management directly done by kernel-level OS (kthreadd)
- A relationship must exist between user threads and kernel threads:
Many-to-One / One-to-One / Many-to-Many Model
- Linux, along with the family of Windows OSs, implement the one-to-one model (-> More concurrency than many-to-one)
- 스레드에 대한 지원은 사용자 수준, 사용자 스레드 또는 커널 스레드에서 제공될 수 있다.
- 사용자 스레드: 사용자 수준 스레드 라이브러리에서 관리
- 커널 스레드: 커널 수준 OS(kthreadd)에 의해 직접 관리됩니다.
- 사용자 스레드와 커널 스레드 사이에 관계가 있어야 한다.
다대일/일대일/다대다 모델
- Linux는 Windows OS 제품군과 함께 일대일 모델을 구현한다(-> 다대일보다 동시성이 높음).
스레드 지원: 사용자 스레드, 커널 스레드
사용자와 커널 스레드 사이에 관계가 있어야 한다.
Threading Issue: The fork() and exec() System Calls
- The semantics of the fork() and exec() change in a multithreaded program
- exec() usually works as normal – replace the running process including all threads
- If one thread in a program calls fork(), does the new process duplicate all threads, or is the new process single-threaded?
- Some UNIX systems have two versions of fork(), one that duplicate all threads (i.e., fork()) and another that duplicate only the calling thread (i.e., fork1()) -> Which of the 2 versions of fork() to use depends on the application:
- If the separate process does not call exec() after forking, the separate process should duplicate all threads
- If exec() is called immediately after forking, the new process duplicates only the calling thread
- 다중 스레드 프로그램에서 fork()와 exec()의 의미 변화
- exec()는 일반적으로 정상적으로 작동하며 모든 스레드를 포함하여 실행 중인 프로세스를 교체한다.
- 프로그램의 스레드 하나가 fork()를 호출하면, 새로운 프로세스는 모든 스레드를 복제하는가, 아니면 새로운 프로세스는 싱글 스레드인가?
- 일부 유닉스 시스템에는 두 가지 버전의 포크()가 있는데, 하나는 모든 스레드(즉, fork()를 복제하는 것이고 다른 하나는 호출 스레드(즉, fork1())만 복제하는 것이다.
- 분리된 프로세스가 forking 후 exec()을 호출하지 않으면 분리된 프로세스는 모든 스레드를 복제해야 한다.
- forking 직후 exec()이 호출되면 새 프로세스는 호출 스레드만 복제한다.
다중 스레드에서 fork()
exec(): 모든 실행 중인 프로세스 교체
fork(): 두 가지 버전. 모든 스레드 복제, 호출 스레드만 복제
호출 스레드만 복제하는 방법: 분리된 프로세스가 forking 후 exec() 호출
Linux Threads
- Linux uses the term task rather than thread (or process)
- Thread creation is done through clone() system call
- It behaves identically to fork(), except that it accepts as arguments a set of flags that dictate what resources are shared between the parent and child (whereas a process created with fork() shares no resources with its parent)
- Thus, when clone() is invoked, it is passed a set of flags that determine how much sharing is to take place between the parent and the child tasks
- Linux는 스레드(또는 프로세스)가 아닌 task라는 용어를 사용한다.
- 스레드 생성은 clone() 시스템 호출을 통해 수행된다.
- fork()와 동일하게 동작하지만, fork()로 생성된 프로세스가 부모와 리소스를 공유하지 않는 반면, 부모와 자식 사이에 공유되는 리소스를 지시하는 flag 집합을 인수로 받아들인다.
- 따라서 clone()이 호출되면 상위 태스크와 하위 태스크 간에 수행할 공유 양을 결정하는 flag 집합이 전달된다.
Linux는 스레드(또는 프로세스) 대신 task 사용
스레드 생성은 clone()으로 수행
fork()와 동일하게 동작, 생성된 프로세스는 공유되는 리소스를 지시하는 flag 집합을 인수로 받아들임
clone()이 호출되면 flag 집합이 전달
- Some of these flags
- 깃발들 중 일부는 다음과 같다.
Linux Threads
- If none of these flags is set when clone() is invoked, the associated resources are not shared, resulting in functionality similar to that of the fork() system call
• fork() is nothing more than a special case of clone() that copies all subcontexts, sharing none
- clone()이 호출될 때 이러한 플래그가 설정되지 않으면 관련 리소스가 공유되지 않으므로 fork() 시스템 호출과 유사한 기능이 발생합니다.
• fork()는 모든 하위 컨텍스트를 복사하는 클론clone()의 특별한 경우에 지나지 않으며, 아무것도 공유하지 않습니다.
clone()이 호출될 때 flag 설정 안하면 리소스 공유 x, fork() 호출과 유사한 기능
fork()는 clone()의 하위. fork()는 아무것도 공유하지 않는다.