Thread

유석현(SeokHyun Yu)·2023년 4월 13일
0

분산 시스템

목록 보기
17/27
post-thumbnail
post-custom-banner

프로세스(process)는 현재 가상 프로세서에서 실행 중인 프로그램으로, OS는 이러한 프로세스들을 실행하기 위해 가상 프로세서를 생성한다.

각 프로세스는 독립된 메모리 공간 가지며, CPU 등의 하드웨어 자원을 공유할 수 있다.

그러나 다른 프로세스의 행위에 대한 영향을 받지 않도록 OS는 각 프로세스에 대해 보안을 유지한다.

그리고 멀티태스킹을 위해 CPU는 여러 프로세스 사이에서 전환(context switch)된다.

하지만 프로세스 간 전환은 상대적으로 비용이 많이 든다.

새로운 프로세스를 생성할 때마다, OS는 완전히 독립된 주소 공간을 생성해야 한다.

또한 CPU를 프로세스 간에 전환하기 위해서는 CPU 상태를 저장하고, 메모리 매핑을 수정하고, 주소 변환 캐시를 무효화하고, 가상 메모리를 사용하는 경우 메인 메모리와 디스크 사이에서 프로세스를 교환해야 한다.

반면 스레드는 프로세스 내에서 실행되는 코드의 일부로, 다른 스레드와 독립적으로 실행된다.

스레드는 CPU 등의 하드웨어 자원을 공유할 수 있지만, 프로세스처럼 각각의 독립된 메모리 공간을 가지지 않는다.

따라서 스레드 간 데이터 보호는 어플리케이션 개발자가 직접 구현해야 한다.

또한 스레드는 프로세스와 달리 동시성 투명성(concurrency transparency)을 보장하지 않으며, 이는 개발자가 스레드 간 동시성 문제를 직접 해결해야 한다는 의미이다.

이에 따라 멀티 스레드 애플리케이션의 성능은 보통 싱글 스레드 애플리케이션보다 좋을 수 있지만, 스레드 간 보호를 위해 추가적인 개발 노력이 필요하다.


Thread usage in nondistributed systems

스레드는 하나의 프로세스 내에서 병렬성(parallelism)을 실현할 수 있게 해준다.

단일 스레드 프로세스에서는 블로킹 시스템 콜이 실행될 경우, 전체 프로세스가 완료될 때까지 블로킹된다.

예를 들어, 스프레드시트 프로그램에서 사용자가 값을 계속해서 변경하는 경우, 해당 셀이 수정될 때마다 의존하는 모든 셀이 자동으로 업데이트된다.

단일 스레드라면 계산과 입력을 동시에 제공하기 어렵기 때문에, 프로그램이 입력을 기다리는 동안 계산이 진행될 수 없거나, 계산을 기다리는 동안 입력이 진행될 수 없는 상황이 발생한다.

하지만 멀티 스레드 프로세스에서는 여러 스레드를 사용하여 병렬성을 실현할 수 있다.

예를 들어, 스프레드시트 프로그램에서는 사용자와 상호작용을 담당하는 스레드와 스프레드시트를 업데이트하는 스레드 두 개의 스레드를 사용할 수 있다.

이렇게 하면 사용자와 상호작용하는 동안 계산이 계속 진행될 수 있으며, 프로그램의 반응성(responsiveness)이 향상된다.


Threads in distributed systems

분산 시스템에서 스레드는 블로킹 시스템 콜을 수행할 때, 전체 프로세스를 블로킹하지 않고 해당 스레드만 블로킹하여 대기할 수 있도록 해준다.

이는 클라이언트-서버 통신과 같은 다중 논리적 연결을 유지하는 통신에서 매우 유용하다.

따라서 스레드를 이용하면 분산 시스템에서 효과적인 통신을 구현할 수 있다.

또한 스레드를 이용하면 다중 논리적 연결을 동시에 유지하는 것이 쉬워지므로, 분산 시스템에서 효과적인 클라이언트-서버 통신을 구현하는 데도 유용하다.


multithreaded clients

분산 시스템에서 멀티스레드 클라이언트를 사용하는 것은 통신 지연(Communication latency)을 숨기는 데에 유용하다.

외부 네트워크에서 딜레이는 수백 밀리초에서 몇 초까지 이어질 수 있으므로, 클라이언트는 통신을 시작한 후 다른 작업을 진행할 수 있어야 한다.

이를 위해 웹 브라우저와 같은 애플리케이션에서는 데이터를 전부 받기 전에도 일부 데이터를 먼저 보여줄 수 있다.

이를 가능하게 하는 것은 멀티스레드를 사용하여 여러 개의 병렬적인 데이터 스트림을 동시에 처리할 수 있기 때문이다.

많은 경우, 웹 서버는 여러 대의 컴퓨터에 복제된다.

이 경우, 클라이언트는 여러 서버에 대한 연결을 동시에 설정하여 데이터를 병렬로 전송할 수 있다.

이를 위해 라운드 로빈 전략이나 로드 밸런싱 기술을 사용하여 요청을 전송한다.

이를 통해 모든 데이터를 받을 때까지 기다리지 않아도 일부 데이터를 먼저 보여줄 수 있으므로, 사용자는 웹 페이지를 더 빠르게 확인할 수 있다.


multithreaded server

분산 시스템에서 멀티스레드를 사용하는 가장 일반적인 경우는 고성능을 위해 서버 측에서 사용된다.

파일 서버의 경우, 디스크에서 대기하는 동안 서버가 블로킹되는 상황을 방지하기 위해 멀티스레딩이 적용된다.

이를 위해, 파일 서버는 디스패처와 여러 개의 워커 스레드를 사용한다.

디스패처는 파일 작업 요청을 읽고, 요청을 처리할 워커 스레드를 선택하여 요청을 전달한다.

워커 스레드는 로컬 파일에서 블로킹 읽기를 수행한다.

만약 워커 스레드가 일시 중단되면, 다른 워커 스레드가 실행된다.

이 방법을 통해 디스크에서 대기할 때도 다른 요청을 처리할 수 있어 파일 서버의 성능이 향상된다.

멀티 스레드를 사용하지 않는 파일 서버의 경우, 서버는 요청을 받은 후 처리가 완료될 때까지 대기한다.

디스크에서 대기하는 동안 서버는 대기하면서 다른 요청을 처리할 수 없으므로, 처리 속도가 저하된다.

따라서 이렇게 싱글 스레드로 동작하는 파일 서버의 경우, 블로킹 시스템 콜을 수행할 때는 큰 유한 상태 머신(finite-state machine)으로 서버를 실행한다.

요청이 들어오면 단일 스레드는 요청을 분석하고, 캐시에서 요청을 처리할 수 있는 경우 바로 처리한다.

캐시에서 요청을 처리할 수 없는 경우, 디스크로 메시지를 보내지만 디스크에서 읽어오는 작업이 끝날 때까지 블로킹하지 않는다(non-blocking).

대신, 현재 요청의 상태를 테이블에 기록하고 다음 메시지를 가져온다.

다음 메시지는 새로운 작업을 요청하는 경우도 있고, 이전 작업에 대한 디스크의 응답인 경우도 있다.

이러한 방식으로 논블로킹 호출을 사용하여 서버를 작동시키며, 메시지를 보내고 받을 때마다 계산 상태를 명시적으로 저장하고 복원해야 한다.

이 방법은 이벤트를 받아들이고 이벤트에 대해 반응하는 유한 상태 머신으로 서버를 운영하는 것이다.

블로킹 시스템 콜은 프로그래밍을 쉽게 만들어준다.

병렬성(parallelism)은 성능을 향상시킨다.

따라서 스레딩을 사용하면 순차적인 프로세스를 유지하면서도 병렬성을 확보할 수 있어 블로킹 시스템 콜과 성능 향상 모두를 동시에 달성할 수 있다.

profile
Backend Engineer
post-custom-banner

0개의 댓글