Q. 프로세스와 스레드의 차이에 대해서 아시나요?
프로세스는 OS로부터 메모리를 할당받아 실행중인 프로그램을 의미합니다.
각각의 프로세스는 독립적인 주소 공간을 가지며 별도의 메모리 영역을 사용합니다.
스레드는 프로세스 내에서 실행되는 흐름의 단위로 하나의 프로세스에서 병렬로 실행될 수 있으며, 같은 프로세스 내 스레드는 스택을 제외한 나머지 메모리를 공유하여 프로세스에 비하여 간단한 스레드 간 통신을 제공합니다.
예를 들어 활성화된 하나의 프로세스인 브라우저의 탭 내에서 플러그인을 다운받거나 파일을 로딩하는 작업 하나하나가 스레드로 구분되어 실행됩니다.
Q. 프로세스 내의 메모리 공간에 대해서 더 자세히 설명해주세요.
프로세스는 코드, 데이터, 스택, 힙 영역으로 구분됩니다.
코드 영역은 실행할 프로그램의 코드가 저장되고 데이터 영역에는 전역 변수와 정적 변수가 저장됩니다.
스택 영역은 지역변수와 매개변수 등 함수 호출에 따라 일시적인 데이터를 저장하고 함수가 반환되면 소멸하는 영역입니다. 함수 단위로 독립적인 공간을 갖기에 스레드는 해당 공간을 공유하지 않습니다.
힙 영역은 동적으로 할당되는 데이터 영역으로 런타임 시에 크기가 결정됩니다.
Q. 멀티 스레딩과 멀티 프로세싱에서 발생하는 컨택스트 스위칭에 대해서 설명해주세요
멀티 스레딩 중 유저 레벨의 스레드는 OS 단의 컨택스트 스위칭이 발생하지 않지만 커널 레벨 스레드는 멀티 프로세싱과 마찬가지의 컨택스트 스위칭이 발생합니다.
하지만 멀티 프로세싱에서의 컨텍스트 스위칭은 현재 프로세스의 상태를 PCB에 저장하고 새로운 프로세스의 상태를 PCB에서 읽어들이면서 가상 메모리 관련 주소 처리를 해야 하고, CPU 캐시 메모리를 초기화하는 비용, 그리고 프로세스 스케줄링 비용이 오버헤드로 발생합니다.
멀티 스레딩에서 스케줄링 비용은 마찬가지로 발생하지만, PCB를 변경하지 않고 훨씬 가벼운 TCB 정보만 변경하고 가상 메모리 관련 처리와 CPU 캐시 메모리 초기화 비용이 발생하지 않아 멀티 스레딩이 더 가볍습니다.
Q. 그러면 멀티 스레딩만 사용하면 되나요?
아니요. 멀티 스레딩이 가볍다는 장점이 존재하지만, 멀티 스레드는 하나의 스레드에서 문제가 발생하면 모든 스레드가 메모리를 공유하기 때문에 다른 스레드도 영향을 받아 전체 프로그램이 종료될 수 있습니다.
반면 멀티 프로세싱은 하나의 프로세스에 문제가 발생하더라도 다른 프로세스에 영향을 주지 않고 정상 동작을 할 수 있어 안정성 면에서 장점이 있습니다.
Q. 그러면, 웹서버는 멀티 프로세스로 구현되어있나요 멀티 스레드인가요?
웹 서버 마다 구현이 다릅니다.
웹 서버 중 아파치는 기본적으로 멀티 프로세스지만 멀티 스레드를 함께 지원합니다.
Nginx는 멀티 프로세스와 싱글 스레드를 지원합니다. 하나의 마스터 프로세스가 여러 워커 프로세스를 관리하고 각각의 워커 프로세스는 싱글 스레드 방식으로 동작합니다.
WAS지만 톰캣은 스레드 풀 기반의 멀티 스레드를 지원하고 있습니다.
Q. 자바나 파이썬에서 멀티 프로세스와 멀티 스레드 구현 방법은 어떻게 되나요?
JAVA의 JVM은 기본적으로 하나의 프로세스로 동작합니다.
자식 프로세스를 만들수 있긴 하지만 시스템 자원을 많이 소모하여 지양하는 패턴입니다.
JAVA는 멀티 스레드를 통해 대부분의 병렬 처리를 하도록 합니다.
반면 python은 자식 프로세스를 통한 멀티 프로세싱을 지원합니다.
하지만 멀티 스레딩에서 GIL에 대한 제약 조건이 존재하여 CPU에 대한 병렬적인 연산이 불가능합니다.
즉, python에서 멀티 스레드는 I/O 바운드에 대해서 사용되고 멀티 프로세스는 CPU 바운드에서 사용됩니다.
Q. 멀티 쓰레드의 동시성과 병렬성을 설명해주세요.
동시성은 하나의 CPU에서 여러 스레드들이 시간을 분할하여 순차적으로 실행되는 것으로 짧은 시간에 여러 스레드가 동작하여 동시에 여러 스레드가 처리되는 것처럼 보이는 것입니다.
병렬성은 여러 CPU 코어를 가지는 컴퓨터에서 스레드 별로 다른 CPU에서 명령어를 실행하며 동시에 여러 동작을 할 수 있도록 하는 것입니다.
Q. 다수의 쓰레드가 공유 데이터에 동시에 접근하는 경우의 문제를 해결하는 방법을 설명해주세요
뮤텍스나 세마포어를 사용하여 데이터의 동시 접근을 막을 수 있습니다.
뮤텍스와 세마포어는 락을 통해 크리티컬 섹션에 동시에 접근할 수 있는 스레드의 개수를 제한합니다.
뮤텍스는 1개, 세마포어는 1개 이상의 스레드가 동시에 접근할 수 있도록 합니다.
Q. 프로세스 격리(Process Isolation) 기술은 프로세스로부터 다른 프로세스들을 보호하도록 설계된 기술입니다. 현대의 운영체제에서는 각각의 프로세스들에 별도의 가상 주소 공간을 제공하고 각 프로세스가 독립된 메모리 공간에서 실행되어 다른 프로세스의 메모리나 자원에 접근할 수 없도록 하는 방식으로 구현합니다.
프로세스 격리 기술의 중요성과 앞서 설명한 구현 방식을 제외하고 어떻게 구현할 수 있을지 말해보세요.
프로세스 격리 기술의 중요성은 다음과 같습니다. 첫 번째로 프로세스 간 보안입니다. 하나의 프로세스에서 발생한 예상치 못한 오류나 악의적인 행위가 다른 프로세스에 영향을 미치지 않도록 보호합니다. 두 번째로 프로세스의 안정성입니다. 프로세스 간 불필요한 간섭을 방지하여 안정성을 높힐 수 있습니다. 세 번째로 자원 관리의 측면에서 중요합니다. 각각의 프로세스가 할당된 자원만을 사용하도록 하여 자원 사용을 효율적으로 관리할 수 있습니다.
프로세스 격리를 구현할 수 있는 방법은 다음과 같습니다. 첫 번째로 OS 가상화를 통해 구현할 수 있습니다. 하이퍼바이저를 통해 하드웨어를 가상화하여 여러 운영체제를 독립적으로 실행시킨다면, 커널 수준의 격리와 보안을 지키는 프로세스 격리를 구현할 수 있지만 리소스 소모가 크며 성능 오버헤드가 발생할 수 있습니다. 두 번째로 컨테이너 기술을 통해 구현할 수 있습니다. 컨테이너는 독립적인 사용자 공간과 의존성을 격리하여 가상화 기술보다 리소스 소모가 적고 빠르지만 운영체제와 커널 영역을 공유하므로 커널 수준의 취약점에 노출될 수 있습니다.