Post

Process 와 Tread

Process

운영체제에 의해서 메모리에 올라가 실행 중인 프로그램

process.png

각각의 프로세스마다 독립적인 메모리 공간을 가지며, 다른 프로세스의 메모리 공간에 접근할 수 없다.
운영체제에 의해 메모리, 입출력 장치 등의 자원을 할당받으며 상태를 갖는다.

프로세스는 최소 하나의 스레드를 갖는다.


멀티 프로세스

여러 개의 프로세스가 동시에 실행되는 것 각 프로세스가 독립적인 메모리 공간을 갖기 때문에 하나의 프로세스가 죽어도 다른 프로셋스에 영향을 끼치지 않는다.
하지만 독립적인 공간을 갖기 때문에 메모리 사용량이 많고 프로세스 간의 통신이 복잡하다.




Thread

프로세스 내에서 동시에 실행되는 작업의 단위로 프로세스안에서 동시에 여러 작업들을 수행할 수 있게 해주는 프로세스 안의 작은 프로세스(경량 프로세스 또는 쓰레드)이다.

thread.png

프로세스 내에서 스택 영역만 따로 할당 받고 그 외의 코드, 데이터, 힙 영역은 공유한다.

프로세스 내에 존재하며 프로세스가 할당받은 자원을 이용하여 실행되며, 스레드는 프로세스 내에서 동시에 여러 작업을 효율적으로 처리하기 위해 존재한다.


멀티 스레드

하나의 프로세스 안에서 여러 개의 스레드가 병렬적으로 실행되는 방식
CPU 자원을 효율적으로 사용할 수 있고, 응용 프로그램의 성능을 향상시킬 수 있다.
여러 스레드가 하나의 프로세스 내에서 실행되기 때문에, 각 스레드는 별도의 메모리 공간을 할당받지 않고, 프로세스의 자원을 공유한다.
프로세스 간 문맥 전환에 비해, 스레드 간 문맥 전환이 빨라 성능이 좋다. 하지만, 하나의 스레드에 문제가 발생하면 전체 스레드가 영향을 받는 동기화 문제가 발생할 수 있다.

멀티 스레드 환경에서의 주의사항

다수의 스레드가 공유 자원에 동시에 접근하게 되는 경우, 동시성 문제가 발생할 수 있다.
이를 해결하기 위해 동기화 메커니즘을 사용하여 자원의 일관성을 보장해야 한다.
두 개 이상의 스레드가 서로 자원을 점유한 상태에서 다른 스레드가 사용 중인 자원을 무한정으로 대기하는 데드락에 빠질 수 있다.
데드락을 방지하기 위해서는 자원 획득 순서나 락을 걸어야 한다.




멀티 스레드의 동시성과 병렬성

동시성은 싱글 코어에서 멀티 작업을 위해 여러 개의 스레드를 실행하는 것이다.

동시에 여러 개의 스레드를 실행하는 것으로 보이지만 실제로는 시분할로 빠르게 번갈아 가면서 실행된다.
스레드가 교대로 공유 자원에 접근하게 되는데, 이로 인해 데이터의 일관성 문제가 발생할 수 있다.

1. 작업 교대의 불예측성

스레드 스케줄링을 예측할 수 없고, 언제든지 다른 스레드로 작업이 교체될 수 있다.
이로 인해서 스레드가 공유자원에 접근하고 있는 도중에, 다른 스레드가 그 자원에 접근하게 되면, 데이터의 일관성이 깨질 수 있다.

2. 중간상태의 노출

한 스레드가 공유 자원을 업데이트하는 동안 다른 스레드가 그 자원을 읽거나 수정할 수 있다.
만약 첫 번째 스레드가 아직 작업을 완료하지 않은 상태에서 두 번째 스레드가 자원에 접근하면, 두 번째 스레드는 불완전한 중간 상태의 데이터에 접근하게 된다.

3. 경쟁 상태

경쟁상태는 여러 스레드가 동시에 공유자원에 접근하여 그 자원을 변경하려고 할 때 발생한다.

두 스레드가 동시에 변수를 증가시키려고 하면 각각의 스레드가 읽고 수정하는 과정에서 서로의 작업을 덮어쓰기할 수 있다.


1
2
병렬성은 멀티 코어에서 다중 작업을 처리하기 위해 여러 개의 스레드를 동시에 실행하는 것이다.  
즉, 여러 코어가 독립적으로 스레드를 실행하기 때문에, 각 스레드는 물리적으로 동시에 실행된다.  

동시성은 주로 작업을 교대로 실행하는 것에 중점을 두고, 병렬성은 실제로 동시에 실행되는 점에서 차이가 있다.



스레드를 많이 띄우면 좋을까?

스레드를 사용하면 동시에 여러 작업을 처리할 수는 있지만, 너무 많은 스레드를 띄우는 경우 성능 저하와 동시성 문제를 일으킬 수 있다.

  1. 운영체제는 스레드간의 컨텍스트 스위칭을 해주는데 스레드가 많아지게 되면, 컨텍스트 스위칭이 더 자주 일어나게 된다.
    따라서, CPU의 시간을 소모하게 되어 성능이 떧어질 ㅅ수 있다.

  2. 또한 공유 자원에 접근할 때 동시성 문제가 발생할 위험이 있어 동기화를 사용해야 하는데, 이 과정에서 병목 현상이 발생할 수 있다.

만 개의 스레드를 생성한다고 가정했을 때 스택의 크기가 기본값인 1MB라면, 스택 메모리는 10GB일 것이다.

또한 스레드당 메타데이터가 추가로 필요하기 때문에 메모리를 더 차지하게 된다.
결과적으로 많은 수의 스레드를 사용하는 것은 메모리 소모가 크다.

따라서 스레드 풀을 사용하여 일정 수의 스레드를 재사용하여 메모리 사용량을 줄이는 것이 좋다. 또한 컨텍스트 스위칭은 프로세스나 스레드의 상태를 저장하고 복원하는 작업인데 비용이 대략 1000사이클에서 10000사이클로 추정된다.

0이 들어있는 변수에 10개의 스레드가 동시에 접근해서 ++ 연산을 하면 왜 10이 나오지 않을까?

이유는 동시성 때문이다.
++ 연산은 원자적이지 않기 때문이다.
++는 사실 두 단계로 나뉜다. 1. 현재 값을 읽고, 2. 1을 더한 후 변수에 다시 덮어쓰는 동작이다. 여러 스레드가 동시에 변수를 수정할때, 각 스레드가 작업을 수행하ㅏ는 동안 다른 스레드도 값을 변경할 수 잇따.

이로 인해서 다른 스레드는 변경된 값을 읽지 못하고 작업을 수행해, 최종 결과가 잘못될 수 잇다.

메모리에 대한 접근은 스레드 간 순서가 보장되지 않기 때문에, 특정 스레드가 어떤 값을 메모리에 쓸 때 다른 스레드가 그 값을 읽는 타이밍에 따라 결과가 달라질 수 있다.

This post is licensed under CC BY 4.0 by the author.