Heap, Data, Code 영역의 공유
- 쓰레드는 메모리를 공유한다. (Heap, Data, Code)
동시접근에 있어서의 문제점
[EXAMPLE]
현재 변수 total의 값은 10이고 두 개의 쓰레드가 각각 6과 9를 더하는 상황이라고 가정해 보자.
6을 더하는 쓰레드를 A쓰레드, 9를 더하는 쓰레드를 B쓰레드라고 하겠다.
CPU는 현재 A쓰레드 과정에 있다. 6을 더한 16을 이제 메모리에 저장하면 된다. 그런데 이때 스케줄러에 의해서 실행 대상이 A쓰레드에서 B쓰레드로 이동하였다.
A쓰레드의 연산 값을 임시저장하고, B쓰레드는 total 값 10을 갖고와 9를 더해 19가 되었다.
B쓰레드의 연산결과인 19가 total에 저장되고 다시 A쓰레드로 바뀌었다.
A쓰레드는 임시저장했던 16을 total에 저장하였다. 최종적으로 10 + 6 + 9 는 25인데 total에는 16이 들어있다.
※ 실행 중인 쓰레드의 변경이 프로그램 라인 단위로 이뤄진다고 생각하면 안된다. printf, scanf, 각종 연산자 들이 실행하는 중간에도 쓰레드의 변경에 의해서 컨텍스트 스위칭은 빈번하게 발생한다.
> 따라서 둘 이상의 쓰레드가 같은 메모리 영역을 동시에 참조하는 것은 문제를 일으킨다. (임계영역)
프로세스로부터의 쓰레드 분리
쓰레드는 스택이외의 모든 것을 공유하기 때문에, 프로세스의 핸들 테이블까지도 공유를 한다.
쓰레드역시 생성과 동시에 UsageCount가 2가 된다. 하나는 쓰레드 종료 시 감소하고, 하나는 쓰레드 핸들을 인자로 CloseHandle 함수가 호출될 때 감소한다.
따라서 쓰레드 생성 시 반환된 핸들값을 인자로 전달하여 CloseHandle함수를 곧바로 호출한다.
> 프로세스로부터 쓰레드를 분리한다. (쓰레드 종료 시 바로 쓰레드의 리소스를 반환 하기 위해)
ANSI 표준 C라이브러리와 쓰레드
멀티 쓰레드 기반으로 프로그램 구현 시 ANSI 표준 함수의 호출은 메모리의 동시 참조 문제가 발생할 수 있다.
> 멀티 쓰레드에 안전한 ANSI 표준 라이브러리를 사용한다. (Runtime Library - Multi-threaded)
> 멀티 쓰레드에 안전한 쓰레드 생성 함수를 사용한다. (_beginthreadex)
멀티 쓰레드 기반에서 쓰레드 생성 함수 : _beginthreadex() (내부적으로 CreateThread 함수 호출) <process.h>
- 함수의 전달인자와 순서는 CreateThread와 같다. 자료형만 맞춰주면 된다.
- 쓰레드를 생성하기에 앞서서 쓰레드를 위해, 독립적인 메모리 블록을 할당한다. (CreateThread와의 차이점)
12.4 쓰레드의 우선순위 컨트롤 (0) | 2020.04.19 |
---|---|
12.3 쓰레드의 상태 컨트롤 (0) | 2020.04.19 |
12.1 Windows에서의 쓰레드 생성과 소멸 (0) | 2020.04.19 |
11.2 쓰레드 구현 모델에 따른 구분 (0) | 2020.04.19 |
11.1 쓰레드란 무엇인가? (0) | 2020.04.19 |
댓글 영역