스레드(컴퓨팅)
Thread (computing)
컴퓨터 과학에서, 실행의 스레드는 스케줄러에 의해 독립적으로 관리할 수 있는 프로그램된 명령의 가장 작은 순서인데, 이것은 일반적으로 운영체제의 일부분이다.[1]스레드와 프로세스의 구현은 운영 체제에 따라 다르지만 대부분의 경우 스레드는 프로세스의 구성요소다.주어진 프로세스의 여러 스레드는 (다중 읽기 기능을 통해) 동시에 실행될 수 있으며, 메모리 같은 리소스를 공유하지만, 다른 프로세스는 이러한 리소스를 공유하지 않는다.특히 프로세스의 스레드는 해당 프로세스의 실행 코드와 동적으로 할당된 변수와 특정 시간에 로컬이 아닌 전역 변수의 값을 공유한다.
역사
![]() |
스레드는 1967년 가변적인 업무수(MVT)로 OS/360 멀티프로그래밍에서 "태스크"라는 이름으로 일찍 등장했다.솔처(1966)는 빅터 A 학점이다. 비소츠키는 "쓰레기"라는 용어를 사용한다.[2]
2003년경에는 CPU 주파수의 성장이 코어 수의 증가로 대체되어 다중 코어를 활용하기 위해서는 동시성이 필요하게 되면서 스레딩의 인기가 높아졌다.[3]
프로세스, 커널 스레드, 사용자 스레드 및 섬유
스케줄링은 커널 레벨이나 사용자 레벨에서 할 수 있으며, 멀티태스킹은 선제적으로 또는 협력적으로 할 수 있다.이것은 다양한 관련 개념을 산출한다.
과정
커널 레벨에서 프로세스는 하나 이상의 커널 스레드를 포함하며, 이 스레드는 예약 및 실행의 단위인 반면, 메모리와 파일 핸들 같은 프로세스의 리소스를 공유한다.커널 스케줄링은 일반적으로 사전에 균일하게 수행되거나 덜 흔하게 협력적으로 수행된다.사용자 수준에서 런타임 시스템과 같은 프로세스 자체는 여러 스레드의 실행을 스케줄링할 수 있다.이러한 것들이 에를랑에서와 같이 데이터를 공유하지 않는 경우에는 대개 프로세스라고 하는 반면,[4] 데이터를 공유하는 경우에는 대개 (사용자) 스레드라고 하며, 특히 선제적으로 스케줄링된 경우에는 특별히 (사용자) 스레드라고 부른다.협력적으로 스케줄링된 사용자 스레드는 섬유라고 알려져 있다. 다른 프로세스들은 사용자 스레드를 다르게 스케줄링할 수 있다.사용자 스레드는 커널 스레드에 의해 다양한 방식으로 실행될 수 있다(일 대 일, 다 대 일, 다 대 다)."경량 프로세스"라는 용어는 사용자 스레드 또는 커널 스레드에 사용자 스레드를 스케줄링하기 위한 커널 메커니즘을 다양하게 말한다.
공정은 커널 스케줄링의 "중량" 단위로서, 공정 생성, 파괴 및 전환은 상대적으로 비용이 많이 들기 때문이다.프로세스는 운영 체제에 의해 할당된 리소스를 소유한다.리소스에는 메모리(코드 및 데이터용), 파일 핸들, 소켓, 장치 핸들, 창 및 프로세스 제어 블록이 포함된다.프로세스는 프로세스 격리에 의해 격리되며, 파일 핸들 또는 공유 메모리 세그먼트를 상속하거나 공유 방식으로 동일한 파일을 매핑하는 등의 명시적 방법을 제외하고는 주소 공간이나 파일 리소스를 공유하지 않는다. 프로세스 간 통신을 참조하십시오.프로세스를 만들거나 파괴하는 것은 상대적으로 비용이 많이 든다. 자원을 획득하거나 방출해야 하기 때문이다.프로세스는 일반적으로 미리 다중 작업을 수행하며, 프로세스 전환은 캐시 플러싱과 같은 문제로 인해 컨텍스트 전환의 기본 비용을 넘어 상대적으로 비용이 많이 든다(특히, 프로세스 스위칭은 가상 메모리 주소 지정을 변경하여 무효화를 유발하고 태그가 지정되지 않은 변환 룩사이드 버퍼 플러시).
커널 스레드
커널 스레드는 커널 스케줄링의 "경량" 단위다.각 프로세스 내에 적어도 하나의 커널 스레드가 존재한다.프로세스 내에 여러 커널 스레드가 있는 경우, 동일한 메모리 및 파일 리소스를 공유한다.커널 스레드는 운영체제의 프로세스 스케줄러가 선제적인 경우 선제적으로 멀티태스킹된다.커널 스레드는 스택, 프로그램 카운터를 포함한 레지스터의 복사본, 스레드 로컬 스토리지(있는 경우)를 제외하고 자원을 소유하지 않기 때문에 상대적으로 제작 및 파괴 비용이 저렴하다.또한 스레드 스위칭은 컨텍스트 스위치( 레지스터 및 스택 포인터 저장 및 복원)가 필요하지만 가상 메모리를 변경하지 않으므로 캐시 친화적(TLB 유효)이라는 비교적 저렴하다.커널은 시스템의 각 논리 코어에 하나의 스레드를 할당할 수 있으며(각 프로세서가 멀티스레딩을 지원하는 경우 여러 개의 논리 코어로 분할되거나, 그렇지 않은 경우 물리적 코어당 하나의 논리 코어만 지원하기 때문에), 차단되는 스레드를 스왑 아웃할 수 있다.그러나 커널 스레드는 사용자 스레드보다 교환하는 데 훨씬 더 오래 걸린다.
사용자 스레드
스레드는 사용자공간 라이브러리에서 구현되기도 하는데, 따라서 사용자 스레드라고 불린다.커널은 이들을 알지 못하기 때문에 사용자 공간에서 관리되고 스케줄이 잡힌다.일부 구현에서는 다중 프로세서 시스템(M:N 모델)의 이점을 얻기 위해 사용자 스레드를 여러 커널 스레드 위에 배치한다.가상 머신에 의해 구현되는 사용자 스레드를 녹색 스레드라고도 한다.
사용자 스레드 구현은 일반적으로 전적으로 사용자 공간에 있으므로, 커널과의 상호작용이 전혀 필요하지 않기 때문에 동일한 프로세스 내에서 사용자 스레드 간의 컨텍스트 전환은 매우 효율적이다: 컨텍스트 스위치는 현재 실행 중인 사용자 스레드 또는 섬유 및 t에 의해 사용되는 CPU 레지스터를 로컬로 저장하여 수행할 수 있다.사용자 스레드 또는 섬유에서 필요한 레지스터를 로드하는 경우.스케줄링은 사용자 공간에서 이루어지기 때문에 스케줄링 정책은 프로그램 워크로드의 요구 사항에 더 쉽게 맞출 수 있다.
그러나 사용자 스레드(커널 스레드와 반대로)에서 차단 시스템 호출을 사용하는 것은 문제가 될 수 있다.사용자 스레드 또는 섬유소가 차단하는 시스템 호출을 수행하는 경우, 그 과정에서 다른 사용자 스레드 및 섬유는 시스템 호출을 반환할 때까지 실행될 수 없다.이 문제의 일반적인 예는 I/O를 수행할 때: 대부분의 프로그램은 I/O를 동기적으로 수행하기 위해 작성된다.I/O 작업이 시작되면 시스템 호출이 이루어지며, I/O 작업이 완료될 때까지 돌아오지 않는다.간섭기에는 전체 프로세스가 커널에 의해 "차단"되어 실행될 수 없게 되는데, 이는 동일한 프로세스의 다른 사용자 스레드 및 섬유에 의해 실행되지 않게 된다.
이 문제에 대한 일반적인 해결책(특히 많은 녹색 스레드 구현에 의해 사용됨)은 비차단 I/O를 내부적으로 사용하고 I/O 작업이 진행되는 동안 다른 사용자 스레드 또는 광섬유를 스케줄링하여 전체 프로세스가 아닌 호출 스레드를 차단하는 인터페이스를 구현하는 I/O API를 제공하는 것이다.다른 차단 시스템 호출에도 유사한 솔루션이 제공될 수 있다.또는 동기식 I/O 또는 기타 차단 시스템 호출(특히, 람다 연속성 및/또는 비동기/대기 원형을[5] 포함한 비차단식 I/O 사용)의 사용을 방지하기 위해 프로그램을 작성할 수 있다.
섬유
섬유는 협력적으로 예정된 스케줄링의 훨씬 더 가벼운 단위다. 실행 중인 섬유는 다른 섬유소가 실행될 수 있도록 명시적으로 "수확"해야 하며, 이것은 커널이나 사용자 스레드보다 구현을 훨씬 쉽게 한다.섬유는 같은 공정의 어떤 실에서든 실행되도록 스케줄링될 수 있다.이를 통해 애플리케이션은 커널 스케줄러(애플리케이션에 맞게 조정되지 않을 수도 있음)에 의존하는 대신 스스로 스케줄링을 관리함으로써 성능 향상을 얻을 수 있다.OpenMP와 같은 병렬 프로그래밍 환경은 전형적으로 그들의 임무를 섬유로 구현한다.섬유와 밀접한 관련이 있는 것은 코루틴인데, 코루틴은 언어 수준 구성물인 반면, 섬유는 시스템 수준 구성물이라는 구별이 있다.
스레드 비교 프로세스
스레드는 여러 면에서 기존의 멀티태스킹 운영체제 프로세스와 다르다.
- 스레드는 프로세스의 하위 집합으로 존재하는 반면, 프로세스는 일반적으로 독립적이다.
- 프로세스 내의 여러 스레드가 프로세스 상태뿐만 아니라 메모리 및 기타 리소스를 공유하는 반면, 프로세스는 스레드보다 훨씬 더 많은 상태 정보를 전달한다.
- 프로세스에는 별도의 주소 공간이 있는 반면 쓰레드는 주소 공간을 공유한다.
- 프로세스는 시스템-프로세스 간 통신 메커니즘을 통해서만 상호작용한다.
- 동일한 프로세스에서 스레드 간 컨텍스트 전환은 일반적으로 프로세스 간 컨텍스트 전환보다 더 빠르게 수행됨
Windows NT 및 OS/2와 같은 시스템은 스레드가 싸고 프로세스가 비싸다고 한다. 다른 운영 체제에서는 주소 공간 스위치의 비용을 제외하고는 큰 차이가 없으며, 일부 아키텍처에서는 (명백히 x86) TLB(translation lookaside buffer)가 플러시된다.
스레드 대 프로세스의 장단점은 다음과 같다.
- 스레드의 리소스 소비 감소: 스레드를 사용하면 여러 프로세스를 사용할 때보다 더 적은 리소스를 사용하여 애플리케이션을 운영할 수 있음.
- 단순화된 스레드 공유 및 통신: 프로세스 간 통신(IPC)을 수행하기 위해 메시지 전달이나 공유 메모리 메커니즘이 필요한 프로세스와 달리 스레드는 이미 공유한 데이터, 코드, 파일을 통해 통신할 수 있다.
- 스레드는 프로세스와 충돌한다. 동일한 주소 공간을 공유하는 스레드로 인해 스레드에 의해 수행되는 불법 작업은 프로세스 전체를 충돌시킬 수 있다. 따라서, 한 스레드가 잘못 작동하면 응용 프로그램의 다른 모든 스레드의 처리에 지장을 줄 수 있다.
스케줄링
사전 예방적 Vis-Asvis 협력 스케줄링
운영 체제는 사전 또는 협력적으로 스레드를 예약한다. 일반적으로 다중 사용자 운영 체제는 컨텍스트 전환을 통한 실행 시간에 대한 세부적인 제어를 위해 사전 멀티스레딩을 선호한다.그러나 선제적 스케줄링은 프로그래머가 예상치 못한 순간에 컨텍스트 스레드를 전환하여 잠금 장치 전달, 우선 순위 뒤집기 또는 기타 부작용을 일으킬 수 있다.이와는 대조적으로, 협동 멀티스레딩은 실행 제어를 포기하기 위해 스레드에 의존하므로 스레드가 완료될 때까지 실행되도록 보장한다.이것은 자원을 대기시켜 협력적으로 다중작업된 스레드 블록을 만들거나 집중적인 연산 중 실행 제어를 하지 않아 다른 스레드를 스타팅할 경우 문제를 일으킬 수 있다.
단일 비주얼 멀티 프로세서 시스템
2000년대 초까지만 해도 대부분의 데스크톱 컴퓨터는 하드웨어 스레드에 대한 지원이 없는 단일 코어 CPU 하나만 가지고 있었는데, 이는 스레드 간 전환이 일반적으로 전체 프로세스 컨텍스트 스위치보다 더 빨랐기 때문이다.2002년 인텔은 하이퍼스레딩이라는 이름으로 펜티엄 4 프로세서에 동시 멀티스레딩을 지원했고, 2005년에는 듀얼 코어 펜티엄 D 프로세서를, AMD는 듀얼 코어 Athlon 64 X2 프로세서를 도입했다.
단일 프로세서가 장착된 시스템은 일반적으로 시간 슬라이싱을 통해 멀티스레딩을 구현한다. 즉 중앙처리장치(CPU)가 서로 다른 소프트웨어 스레드 사이에서 전환된다.이러한 컨텍스트 전환은 일반적으로 사용자가 스레드 또는 태스크를 병렬로 실행하는 것으로 인식할 정도로 자주 발생한다(일반적으로 인기 있는 서버/데스크톱 운영 체제의 경우 다른 스레드가 대기 중일 때 스레드의 최대 시간 조각은 100~200ms로 제한됨).멀티프로세서 또는 멀티코어 시스템에서는 모든 프로세서 또는 코어가 동시에 개별 스레드를 실행하는 동시에 다중 스레드가 실행될 수 있으며, 하드웨어 스레드가 있는 프로세서나 코어에서는 별도의 소프트웨어 스레드가 동시에 실행될 수도 있다.
스레딩 모델
1:1(커널 레벨 스레딩)
사용자가 커널의[6] 스케줄링 가능한 엔터티와의 1:1 대응에서 생성한 스레드는 가능한 가장 간단한 스레딩 구현이다.OS/2와 Win32는 처음부터 이 접근법을 사용했고, Linux에서는 GNU C 라이브러리가 이 접근법을 구현했다(NPTL 또는 이전 LinuxThreads를 통해).이 접근방식은 Solaris, NetBSD, FreeBSD, macOS 및 iOS에서도 사용된다.
N:1(사용자 수준 스레딩)
N:1 모델은 모든 애플리케이션 레벨 스레드가 하나의 커널 레벨 스케줄링된 엔티티에 매핑됨을 의미하며,[6] 커널은 애플리케이션 스레드에 대한 지식이 없다.이 접근방식으로 컨텍스트 스위칭은 매우 빠르게 수행될 수 있으며, 게다가 스레딩을 지원하지 않는 단순한 커널에서도 구현될 수 있다.그러나 주요 단점 중 하나는 멀티스레드 프로세서 또는 멀티프로세서 컴퓨터의 하드웨어 가속화의 혜택을 누릴 수 없다는 점이다. 동시에 둘 이상의 스레드가 예약되어 있는 경우는 결코 없다.[6]예를 들면 다음과 같다.스레드 중 하나가 I/O 요청을 실행해야 할 경우 전체 프로세스가 차단되어 스레딩 이점을 사용할 수 없다.GNU 휴대용 스레드는 상태 스레드와 마찬가지로 사용자 수준 스레딩을 사용한다.
M:N(하이브리드 나사산)
M:N 지도 일부M일부에 대한 응용 프로그램 스레드 수N커널 엔티티 [6]수 또는 "가상 프로세서"이것은 커널 레벨("1:1")과 사용자 레벨("N:1") 스레딩 사이의 절충이다.일반적으로 "M:N" 스레딩 시스템은 커널 또는 사용자 스레드보다 구현이 더 복잡하며, 커널과 사용자 공간 코드에 대한 변경이 필요하기[clarification needed] 때문이다.M:N 구현에서 스레딩 라이브러리는 사용 가능한 스케줄링 가능한 엔티티에서 사용자 스레드를 스케줄링할 책임이 있다. 이는 시스템 호출을 피하기 때문에 스레드의 컨텍스트 전환을 매우 빠르게 만든다.그러나 이는 사용자랜드 스케줄러와 커널 스케줄러 간의 광범위한(그리고 비용이 많이 드는) 조정 없이 차선의 스케줄링뿐만 아니라 복잡성과 우선 순위 역전의 가능성을 증가시킨다.
하이브리드 구현 예제
- NetBSD 네이티브 POSIX 스레드 라이브러리 구현의 이전 버전에서 사용하는 스케줄러 활성화(1:1 커널 또는 사용자 공간 구현 모델이 아닌 M:N 모델)
- 이전 버전의 Solaris 운영 체제에서 사용하는 경량 프로세스
- PM2 프로젝트의 마르셀.
- Tera-Cray MTA-2용 OS
- Haskell 언어를 위한 GLC(Glasgow Haskell Compiler)는 운영 체제 스레드에 예약된 경량 스레드를 사용한다.
Unix 시스템의 스레딩 모델 이력
SunOS 4.x는 경량 공정 또는 LWP를 구현했다.NetBSD 2.x+ 및 DragonFly BSD는 LWP를 커널 스레드(1:1 모델)로 구현한다.SunOS 5.2 ~ SunOS 5.8 및 NetBSD 2 ~ NetBSD 4는 각 커널 스레드에 하나 이상의 사용자 레벨 스레드를 멀티플렉싱하는 2 레벨 모델을 구현했다(M:N 모델).SunOS 5.9 이상과 NetBSD 5는 사용자 스레드 지원을 제거하여 1:1 모델로 복귀했다.[7]FreeBSD 5는 M:N 모델을 구현했다.FreeBSD 6은 1:1과 M:N을 모두 지원하며, 사용자는 /etc/libmap.conf를 사용하여 주어진 프로그램과 함께 사용할 프로그램을 선택할 수 있다.FreeB로 시작SD 7, 1:1이 디폴트가 되었다.FreeBSD 8은 더 이상 M:N 모델을 지원하지 않는다.
단일 스레드 및 다중 스레드 프로그램
컴퓨터 프로그래밍에서 단일 스레딩은 한 번에 하나의 명령을 처리하는 것이다.[8]변수의 의미론과 공정 상태에 대한 공식 분석에서 단일 스레딩이라는 용어는 기능 프로그래밍 커뮤니티에서 흔히 볼 수 있는 "단일 스레드 내 역추적"을 의미하기 위해 다르게 사용될 수 있다.[9]
멀티스레딩은 주로 멀티태스킹 운영 체제에서 발견된다.멀티스레딩(Multithreading)은 하나의 프로세스의 컨텍스트 내에 여러 개의 스레드가 존재할 수 있도록 하는 광범위한 프로그래밍 및 실행 모델이다.이러한 스레드는 프로세스의 리소스를 공유하지만 독립적으로 실행할 수 있다.스레드 프로그래밍 모델은 개발자들에게 동시 실행의 유용한 추상화를 제공한다.다중 처리 시스템에서 병렬 실행이 가능하도록 멀티스레딩을 한 프로세스에 적용할 수도 있다.
멀티스레딩 라이브러리는 새로운 스레드를 만들기 위해 함수 호출을 제공하는 경향이 있는데, 함수를 매개 변수로 사용한다.그런 다음 전달된 함수의 실행을 시작하고 함수가 반환될 때 종료되는 동시 스레드가 생성된다.스레드 라이브러리는 데이터 동기화 기능도 제공한다.
스레드 및 데이터 동기화
동일한 프로세스의 스레드는 동일한 주소 공간을 공유한다.이것은 동시에 실행되는 코드를 IPC의 오버헤드나 복잡성 없이 긴밀하게 결합하고 편리하게 데이터를 교환할 수 있게 해준다.그러나 스레드 간에 공유할 때, 간단한 데이터 구조라도 업데이트하기 위해 둘 이상의 CPU 명령이 필요한 경우 경합하기 쉽다. 두 개의 스레드가 동시에 데이터 구조를 업데이트하려고 시도하다가 예기치 않게 변경되는 것을 발견할 수 있다.인종적 조건에 의해 야기되는 벌레는 번식하고 격리시키기가 매우 어려울 수 있다.
이를 방지하기 위해, 응용 프로그램 프로그래밍 인터페이스(API)를 스레딩하면 동시 액세스에 대해 데이터 구조를 잠글 수 있는 뮤텍스와 같은 동기화 기본 요소가 제공된다.유니프로세서 시스템에서는 잠긴 뮤텍스로 실행되는 스레드가 절전 모드여야 하므로 컨텍스트 스위치를 트리거해야 한다.멀티프로세서 시스템에서 스레드는 대신 스핀록에서 뮤텍스를 폴링할 수 있다.이 두 가지 모두 특히 잠금의 세밀도가 너무 미세한 경우 대칭 다중 처리(SMP) 시스템의 프로세서가 성능을 약화시키고 메모리 버스를 다투게 할 수 있다.
다른 동기화 API에는 조건 변수, 중요 섹션, 세마포어 및 모니터가 포함된다.
스레드 풀
스레드를 포함하는 일반적인 프로그래밍 패턴은 시작 시 설정된 수의 스레드가 생성된 다음 작업이 할당되기를 기다리는 스레드 풀의 그것이다.새 태스크가 도착하면 깨워 태스크를 완료한 후 대기 상태로 돌아간다.이를 통해 수행되는 모든 작업에 대해 상대적으로 비용이 많이 드는 스레드 생성 및 파괴 기능을 방지하고 애플리케이션 개발자의 손에서 스레드 관리를 빼앗아 스레드 관리를 최적화하는 데 더 적합한 라이브러리 또는 운영 체제에 맡긴다.
다중 스레드 프로그램 대 단일 스레드 프로그램 장단점
다중 스레드 애플리케이션은 단일 스레드 애플리케이션과 비교하여 다음과 같은 장점이 있다.
- 응답성: 다중 스레딩은 응용 프로그램이 입력에 계속 응답할 수 있도록 할 수 있다.원스레드 프로그램에서 주 실행 스레드가 장기간 실행되는 작업에서 차단되면 전체 애플리케이션이 정지하는 것처럼 보일 수 있다.이러한 장기 실행 작업을 주 실행 스레드와 동시에 실행되는 작업자 스레드로 이동함으로써 백그라운드에서 작업을 실행하는 동안 애플리케이션이 사용자 입력에 대한 응답성을 유지할 수 있다.한편, 대부분의 경우, 멀티스레딩만이 프로그램 응답성을 유지하는 유일한 방법은 아니며, 비차단 I/O 및/또는 Unix 신호는 유사한 결과를 얻기 위해 사용할 수 있다.[10]
- 병렬화: 다중 코어 또는 다중 CPU 시스템을 사용하려는 애플리케이션은 멀티스레딩을 사용하여 데이터와 작업을 병렬 하위 작업으로 분할하고 기본 아키텍처가 하나의 코어에서 동시에 또는 여러 코어에 병렬로 스레드가 실행되는 방법을 관리할 수 있도록 할 수 있다.CUDA와 OpenCL과 같은 GPU 컴퓨팅 환경은 수십 개에서 수백 개의 스레드가 많은 코어의 데이터에서 병렬로 실행되는 멀티스레딩 모델을 사용한다.결과적으로, 이것은 더 나은 시스템 활용을 가능하게 하고, (동기화 비용이 이익을 흡수하지 않는다면) 더 빠른 프로그램 실행을 제공할 수 있다.
멀티스레드 애플리케이션에는 다음과 같은 단점이 있다.
- 동기화 복잡성 및 관련 버그: 나사산 프로그램에 일반적인 공유 리소스를 사용할 때 프로그래머는 경기 조건과 기타 비직관적 행동을 피하도록 주의해야 한다.데이터를 올바르게 조작하기 위해서는 종종 스레드가 정확한 순서로 데이터를 처리하기 위해 제때에 랑데부해야 한다.또한 스레드는 공통 데이터가 다른 스레드에 의해 수정되는 동안 한 스레드에서 읽히거나 덮어쓰지 않도록 상호 배타적인 작업(흔히 뮤텍스를 사용하여 구현)이 필요할 수 있다.그러한 원시성의 부주의한 사용은 교착상태, 라이브록 또는 자원 경쟁으로 이어질 수 있다.에드워드 A처럼. 이 교수는 "사슬은 순차적 계산에서 작은 단계처럼 보이지만 실은 큰 단계를 나타낸다.그들은 순차적 계산의 가장 필수적이고 매력적인 특성인 이해성, 예측성 및 결정론을 폐기한다.스레드는, 계산의 모델로서, 대단히 결정적이지 않고, 프로그래머의 일은 그 비결정론적인 다듬기 중의 하나가 된다.[11]
- 테스트할 수 없는 존재.일반적으로 멀티스레드 프로그램은 결정적이지 않으며, 그 결과 테스트할 수 없다.즉, 다중 스레드 프로그램은 시험 시스템에서는 결코 나타나지 않는 버그를 쉽게 가질 수 있으며, 생산에서만 나타날 수 있다.[12][11]이것은 잘 정의된 특정 패턴(예: 메시지 전달)으로 스레드 간 통신을 제한함으로써 완화될 수 있다.
- 동기화 비용.현대 CPU의 스레드 컨텍스트 스위치는 최대 100만 대의 CPU 사이클이 소요될 수 있어 효율적인 멀티스레딩 프로그램 작성을 어렵게 한다.[13]특히 읽기 간 동기화가 너무 빈번하지 않도록 각별한 주의를 기울여야 한다.
프로그래밍 언어 지원
많은 프로그래밍 언어가 어느 정도 용량의 스레딩을 지원한다.
- IBM PL/I(F)는 빠르면 1960년대 후반에 멀티스레딩(멀티태스킹이라고 함)에 대한 지원을 포함하였으며, 이는 Optimizing Compiler 및 이후 버전에서도 계속되었다.IBM Enterprise PL/I 컴파일러는 새로운 모델 "스레드" API를 도입했다.어느 버전도 PL/I 표준의 일부가 아니었다.
- C와 C++의 많은 구현은 스레딩을 지원하며 운영 체제의 네이티브 스레딩 API에 대한 액세스를 제공한다.스레드 구현을 위한 표준 인터페이스는 C 기능 라이브러리 호출의 집합인 POSIX 스레드(Pthreads)이다.OS 벤더는 인터페이스를 원하는 대로 자유롭게 구현할 수 있지만, 애플리케이션 개발자는 여러 플랫폼에 걸쳐 동일한 인터페이스를 사용할 수 있어야 한다.리눅스를 포함한 대부분의 유닉스 플랫폼은 Pthread를 지원한다.Microsoft Windows는 beginthread와 같은 멀티스레딩을 위한 프로세스.h 인터페이스에 자체 스레드 기능 세트를 가지고 있다.
- Java, Python 및 와 같은 일부 상위 수준(일반적으로 교차 플랫폼) 프로그래밍 언어.NET Framework 언어: 런타임에 스레딩 구현 시 플랫폼별 차이를 추상화하는 동시에 스레딩을 개발자에게 노출.몇 개의 다른 프로그래밍 언어와 언어 확장 또한 개발자로부터 동시성과 스레딩의 개념을 완전히 추상화하려고 한다(Cilk, OpenMP, MPI(메시지 전달 인터페이스)).일부 언어는 동시성이나 스레드(Ateji PX, CUDA)를 요구하지 않고 대신 순차 병렬화(특히 GPU를 사용)를 위해 설계된다.
- 일부 해석 프로그래밍 언어에는 글로벌 인터프리터 잠금(GIL)으로 인해 스레딩과 동시성을 지원하지만 스레드의 병렬 실행은 지원하지 않는 구현(예: Ruby의 경우 Ruby MRI, Python의 경우 CPython)이 있다.GIL은 통역이 두 개 이상의 스레드에 있는 애플리케이션 코드를 동시에 해석하지 못하도록 할 수 있는 상호 배제 잠금으로, 복수의 코어 시스템에 대한 병렬화를 효과적으로 제한할 수 있다.이로 인해 프로세서가 필요한 프로세서 바인딩 스레드의 성능이 대부분 제한되며, I/O 바인딩 또는 네트워크 바인딩된 스레드의 성능은 크게 제한되지 않는다.스레드 확장을 사용한 Tcl과 같이 해석된 프로그래밍 언어의 다른 구현은 데이터와 코드가 스레드 간에 명시적으로 "공유"되어야 하는 아파트 모델을 사용함으로써 GIL 제한을 피한다.Tcl에서 각 나사산은 하나 이상의 통역자를 가지고 있다.
- 데이터 병렬 컴퓨팅을 위해 설계된 CUDA와 같은 프로그래밍 모델에서, 일련의 스레드는 메모리에서 데이터를 찾기 위해 ID만 사용하여 동일한 코드를 병렬로 실행한다.본질적으로 애플리케이션은 각 스레드가 병렬로 작동하고 GPU 아키텍처를 사용할 수 있도록 서로 다른 메모리 세그먼트에서 동일한 작동을 수행하도록 설계되어야 한다.
- Verilog와 같은 하드웨어 설명 언어는 매우 많은 수의 스레드를 지원하는 다른 스레딩 모델을 가지고 있다(하드웨어 모델링용).
참고 항목
참조
- ^ Lamport, Leslie (September 1979). "How to Make a Multiprocessor Computer That Correctly Executes Multiprocess Programs" (PDF). IEEE Transactions on Computers. C-28 (9): 690–691. doi:10.1109/tc.1979.1675439. S2CID 5679366.
- ^ 다중 컴퓨터 시스템의 교통 통제, 제롬 하워드 솔처, 1966년 과학 박사 논문, 20페이지의 각주를 참조한다.
- ^ Herb Sutter. "The Free Lunch Is Over: A Fundamental Turn Toward Concurrency in Software".
- ^ "Erlang: 3.1 Processes".
- ^ Sergey Ignatchenko. "Eight Ways to Handle Non-blocking Returns in Message-passing Programs: from C++98 via C++11 to C++20". CPPCON. Archived from the original on 2021-11-04.
- ^ a b c d Gagne, Abraham Silberschatz, Peter Baer Galvin, Greg (2013). Operating system concepts (9th ed.). Hoboken, N.J.: Wiley. pp. 170–171. ISBN 9781118063330.
- ^ "Multithreading in the Solaris Operating Environment" (PDF). 2002. Archived from the original (PDF) on February 26, 2009.
- ^ Raúl Menéndez; Doug Lowe (2001). Murach's CICS for the COBOL Programmer. Mike Murach & Associates. p. 512. ISBN 978-1-890774-09-7.
- ^ Peter William O'Hearn; R. D. Tennent (1997). ALGOL-like languages. Vol. 2. Birkhäuser Verlag. p. 157. ISBN 978-0-8176-3937-2.
- ^ Sergey Ignatchenko. "Single-Threading: Back to the Future?". Overload (97).
- ^ a b Edward Lee (January 10, 2006). "The Problem with Threads". UC Berkeley.
- ^ "Multi-threading at Business-logic Level is Considered Harmful". ACCU.
- ^ 'No Bugs' Hare. "Operation Costs in CPU Clock Cycles".
추가 읽기
- 데이비드 R.부텐호프: POSIX 스레드를 이용한 프로그래밍, 애디슨 웨슬리, ISBN 0-201-63392-2
- 브래드포드 니콜스, 딕 버틀러, 재클린 프룰렉스 파렐: 프스레즈 프로그래밍, 오렐리 & 어소시에이츠, ISBN 1-56592-115-1
- 폴 하이드: 자바 스레드 프로그래밍, 샘스, ISBN 0-672-31585-8
- 짐 베버리지, 로버트 위너:Win32, Addison-Wesley, ISBN 0-201-44234-5의 멀티스레딩 애플리케이션
- 우레쉬 바할리아:Unix Internals: 프렌티스 홀, ISBN 0-13-101908-2
![]() | Wikiversity는 프로세스와 스레드에 대한 학습 자원을 가지고 있다. |