동시성은 여러 작업이 동시에 진행될 수 있는 능력을 의미하며, 이는 프로그램의 효율성을 크게 향상시킬 수 있습니다. 또한 단순히 여러 작업이 동시에 실행되는 것뿐만 아니라, 각 작업이 서로 영향을 미치지 않고 독립적으로 진행될 수 있는 환경을 조성하는 것도 포함합니다. 예를 들어, 웹 서버가 여러 클라이언트의 요청을 동시에 처리할 수 있는 경우가 이에 해당합니다.
이번 글에서는 동시성을 구현하는 여러 방법중에 프로세스와 스레드에 대해 알아보고 가겠습니다.
프로세스란 운영체제로부터 자원을 할당받은 작업의 단위로 실행중인 프로그램을 의미합니다. 각 프로세스는 코드, 데이터, 스택, 힙으로 구성되어 있습니다. 프로세스는 서로 독립적으로 실행되며, 하나의 프로세스가 종료되더라도 다른 프로세스에는 영향을 미치지 않습니다.

스레드는 프로세스가 할당받은 자원을 이용하는 실행 흐름의 단위로 프로세스 내에서 실행되는 작업의 단위입니다. 하나의 프로세스는 여러 개의 스레드를 가질 수 있으며, 이 스레드들은 같은 메모리 공간(Code, Data, Heap)을 공유합니다. 스레드는 프로세스보다 가벼운 단위로, 스레드 간의 전환이 프로세스 간의 전환보다 빠릅니다.

프로세스와 스레드는 여러 면에서 차이가 있습니다.
첫째, 프로세스는 독립적인 메모리 공간을 가지지만, 스레드는 같은 프로세스 내에서 메모리를 공유합니다. 프로세스의 경우 위에서 언급했듯이 하나의 프로세스가 종료되더라도 다른 프로세스에 영향을 미치지 않습니다. 하지만 스레드의 경우 스레드가 종료되면 같은 프로세스 내의 다른 스레드들도 모두 종료되는데 이는 같은 프로세스 내에서 자원이 공유되기 때문입니다.
둘째, 프로세스 간의 통신은 복잡하지만, 스레드 간의 통신은 상대적으로 간단합니다. 프로세스의 경우 서로 다른 메모리 공간을 가지기 때문에, 소켓, 파이프, 메시지 큐 등의 기법을 사용하여 데이터를 주고받아야 합니다. 이러한 방법들은 추가적인 오버헤드를 발생시킵니다. 반면에 스레드는 같은 프로세스 내에서 메모리를 공유하므로, 변수를 직접 읽고 쓸 수 있습니다. 이로 인해 스레드 간의 통신이 상대적으로 간단하고 빠릅니다.
셋째, 프로세스는 생성과 종료에 더 많은 자원을 소모하지만, 스레드는 상대적으로 적은 자원을 소모합니다. 프로세스를 생성하거나 종료하는 과정은 운영체제가 새로운 메모리 공간을 할당하고, 프로세스 제어 블록(PCB)을 관리해야 하기 때문에 overhead가 큽니다. 스레드는 같은 프로세스 내에서 생성되므로, 새로운 스레드를 만드는 과정은 상대적으로 간단하고 자원을 적게 소모합니다.
동시성 프로그래밍에서는 여러 작업을 동시에 처리해야 하므로, 이를 위해 프로세스와 스레드를 적절히 활용해야 합니다. 예를 들어, 멀티스레딩을 통해 하나의 프로세스 내에서 여러 작업을 동시에 수행할 수 있습니다. 이는 CPU 자원을 효율적으로 활용할 수 있게 해줍니다.
또한, 동시성 프로그래밍에서는 스레드 간의 안전한 데이터 공유와 동기화가 중요합니다. 이를 위해서는 프로세스와 스레드의 구조를 이해하고, 적절한 동기화 기법을 적용해야 합니다.