Posts ㄹㄹ
Post
Cancel

ㄹㄹ

  • CPU가 하는 일

    다음 두 가지를 계속해서 반복

    1. 메모리에서 명령어를 ‘하나’ 가져온다.
    2. 실행한다.
  • 메모리에 어떻게 접근할까 ?
    • PC 레지스터(레지스터)는 명령어가 적재된 메모리 주소를 저장하고 있음
    • CPU는 이 주소를 참조하여 메모리에
  • 레지스터가 저장하는 주소는 기본적으로 1씩 자동 증가

  • 그럼 첫 명령어 주소 어떻게 적재될까 ?
    • 프로그램이 실행되면 main 함수에 대응하는 첫 번째 기계 명령어를 찾고, loader가 레지스터에 해당 명령어 주소를 적재한다.
  • 소스코드 -> (컴파일) -> 실행파일 (디스크) -> 메모리에 적재

  • 프로세스 -> 실행 정보(context)를 저장하고 있어서, CPU가 여러 프로세스를 왔다갔다 하면서 실행할 수 있다.
    • 즉, 프로세스에 실행 정보가 있기 때문에 중지 후에 어디서부터 다시 실행해야할지 알 수 있다.
    • 이렇게 여러 프로세스를 동시에 실행(하는 것처럼)하는 방식을 ‘멀티태스킹’이라고 한다.
  • 앞서 살펴본 것처럼 명령어 주소를 레지스터에 적재하고 프로세스의 멀티태스킹을 지원하는 등의 작업은 우리가 신경쓸 필요가 없다. ‘OS’가 처리해주기 때문에

  • 프로세스에는 별도의 주소 공간이 할당된다. -> 프로세스 주소 공간 ```

    메모리에 할당된 프로세스 주소 공간


스택 영역 ———

여유 공간


힙 영역 ——— 데이터 영역 ——— 코드 영역 ——— ```

  • 프로세스를 생성할 때는 메모리에서 실행 파일을 적재할 적절한 영역을 찾은 후 CPU의 PC 레지스터를 main 함수의 주소로 세팅해야 한다.
    • 즉, 프로세스에는 ‘하나의 실행흐름(main thread)’만 존재한다.
    • 따라서, funcA 함수와 funcB 함수를 실행하여 각각의 실행 결과를 합치는 작업을 빠르게 하고싶으면, 각각의 함수에 대한 프로세스를 실행한 후 프로세스 간 통신(Inter-Process Communication)을 활용해 통신해야한다.
    • 이런것을 다중 프로세스 프로그래밍이라고 한다.
  • 하지만, 프로세스는 별도의 주소 공간이 필요하고 이로인해 각 프로세스 간의 통신은 더 복잡해진다.
    • 스레드의 필요성 대두
  • 스레드는 하나의 프로세스 내의 주소 공간을 공유한다. (스레드가 프로세스보다 훨씬 가볍고 생성 속도가 빠른 이유)
    • 따라서, IPC 같은 통신이 필요하지 않음
    • 레지스터가 main 함수를 가리키게 할 수 있듯이 다른 어떤 함수라도 가리키게 할 수 있으므로 여러 실행흐름(thread)을 만들 수 있다.
    • 즉, 하나의 프로세스에는 main 이외에도 진입 함수가 있을 수 있으며 하나의 프로세스에 속한 기계 명령어를 CPU 여러 개에서 동시에 실행할 수 있다.
    • 이는 스레드를 생성할때 반드시 진입 함수를 지정해야하는 이유이다.
  • 다중 코어에서 다중 스레드를 활용하여 모든 CPU를 최대한 활용할 수 있게된 것.
    • 하지만, 다중 코어가 있어야지만 다중 스레드를 생성할 수 있는 것은 아니다. 단일 코어에서도 가능하다.
    • 이는 스레드가 OS 레벨에서 구현되기 때문 (코어 개수와 무관)
    • 다중 스레드는 CPU를 최대한 활용하는 것 이외에도 시간이 오래 소요되는 특정 이벤트를 처리하는 별도의 스레드를 생성하는 등으로 사용할 수 있다.
  • 스레드 간에는 통신이 필요하지 않기 때문에 OS에서의 지원도 필요하지 않다.
    • 따라서, 다중 스레드가 공유 리소스에 접근할때 의도하지 않은 결과들이 나타난다.
    • 이는 CPU가 명령어를 실행할 때 스레드를 전혀 고려하지 않기 때문이다.
  • 스레드 하나당 스택 영역에 스택 프레임 하나가 생긴다.
  • 스택 프레임에는 레지스터 초깃값, 지역 변수, 매개 변수, 반환 주소(함수 실행 끝나고 다시 돌아갈 주소) 등이 저장된다.
  • 지역 변수, 매개 변수는 기본적으로 레지스터에 저장된다.
    • 레지스터 개수를 초과하게 되는 변수들은 스택 프레임에 저장된다.
    • 예를 들어, 함수 A가 B를 호출할 때 B에서 지역 변수 등을 레지스터에 저장하면 A에서 저장해놓은게 덮어써지기 때문에, B의 스택 프레임에 레지스터 초깃값(A에서 저장해놓은 것)이 저장된다.

리소스 관점에서 바라보기

  • 스레드는 프로세스 리소스를 공유한다 -> 어떤 리소스 ? -> 힙 영역, 데이터 영역, 코드 영역(read-only)

  • 스레드 전용 리소스 ? -> 스택 영역, 스레드 전용 storage

면접 질문 : 스레드 vs 프로세스

  • 주소 공간
    • 프로세스는 OS로부터 별도의 주소 공간(가상 메모리)을 할당받는다.
    • 스레드는 프로세스의 주소 공간을 공유한다.
  • 통신방식
    • 프로세스 간에는 다른 주소 공간을 사용하기 때문에 OS가 개입해서 프로세스 간 통신이 필요하다
    • 스레드는 같은 주소 공간을 공유하기 때문에 스레드 간 통신은 OS 개입이 필요하지 않다.
  • 실행 흐름
    • 프로세스는 생성시 pc 레지스터에 main 함수 호출 명령어 주소를 적재해야 하기 때문에 하나의 흐름밖에 갖지 못한다.
    • 스레드는 main 함수 외에도 다양한 진입 함수를 지정할 수 있기 때문에 여러 실행 흐름을 만들 수 있다.
  • 동기화 문제
    • 프로세스 간 : 서로 독립적이기 때문에 동기화 문제가 덜함.
    • 스레드 간 : 메모리를 공유하므로 동기화 문제가 발생할 가능성이 높음.

참고 자료


  • 루 샤오펑, 『컴퓨터 밑바닥의 비밀』, 길벗(2024), 2장
This post is licensed under CC BY 4.0 by the author.