-
beginThread & TLS쓰레드/쓰레드 2022. 4. 3. 13:36
C/C++ 언어로 멀티스레드 프로그램을 만드는 경우에는 CreateThread API로 스레드를 생성하는 경우는 드물다. C/C++로 프로그램을 만들 때는 표준 C라이브러리를 이용하는데, 이 경우에는 CreateThread API를 사용해서는 안 된다고 알려져 있기 때문이다. 멀티스레드에 대응되는 라이브러리에는 스레드 생성 함수도 준비되어 있을 것이므로 이를 사용해야 한다.
라이브러리 함수를 이용할 때 CreateThread를 이용해서는 안 되는 이유
- 프로세스 내의 스레드는 메모리 공간을 공유하기 때문에 정적변수를 사용할 때 문제가 생길 수 있다.
예를 들어 표준 C라이브러리 함수의 strtok는 처음 호출했을 때 받은 포인터를 정적변수에 보존하고, 이후에 호출에서는 보존한 값을 참조하게 되어 있다.
그러나 이 정적변수의 값은 다른 포인터를 지정해서 strtok 함수를 호출하면 덮어쓰기가 된다.
싱글스레드라면 프로그램에서 주의하면 끝나지만, 멀티스레드 환경일 경우에는 언제든지 다른 스레드가 strtok 함수를 호출할지 예측할 수 없다. 자신도 모르는 사이에 포인터가 바뀔 가능성이 있다.
이런 사태를 막기 위해 Windows에서는 스레드마다 다른 메모리 영역을 정적으로 할당하는 구조를 제공한다.
이를 스레드 로컬 스토리지(TLS)라고 한다.
beginThread()
beginThread 사용 예)
TLS(Thread Local Storage)
TLS(Thread Local Storage)는 스레드 별로 고유한 저장공간을 가질 수 있는 방법이다.
각각의 스레드는 고유한 스택을 갖기 때문에 스택 변수( 지역 변수)는 스레드 별로 고유하다.
예를 들어서 각각의 스레드가 같은 함수를 실행한다고 해도 그 함수에서 정의된 지역변수는 실제로 서로 다른 메모리 공간에 위치한다는 의미이다. 그러나 정적 변수나 전역 변수의 경우에는 프로세스 내의 모든 스레드에 의해서 공유된다.
TLS는 정적, 전역 변수를 각각의 스레드에게 독립적으로 만들어 주고 싶을 때 사용하는 것이다.
메모리 영역을 쓰레드 관점으로 볼때
각각의 쓰레드는 프로세스를 실행 시키면서 각각의 스택들에서 메모리에 접근을 하지만 (개별공간)
전역 정정 공간은 모든 함수에서 즉, 서로 다른 쓰레드에서 접근이 가능하다.
1.TLS를 사용 하지 않았을때
- foo()라는 함수를 호출하는 쓰레드가 2개 있을때 각각의 쓰레드는 static 즉 전역 정적 공간에 있는 int c 에 접근
- static성질 : 처음 호출 할때 메모리가 생성 되고 그다음 호출 부터는 전에 공간이 생겼으니 무시
- 결과 : 쓰레드 1 실행후 ->쓰레드 2가 실행 되면 쓰레드 2 에는 c의 값이6이 되어버림
1.TLS를 사용
__declsped(thread) static int c=0; << TLS 공간을 생성
이제 각각의 쓰레드는 TLS영역에 int c를 생성 하였기에 쓰레드 1 쓰레드 2 모두 c의 값이 3
'쓰레드 > 쓰레드' 카테고리의 다른 글
스레드 간 동기화 ,동기화가 필요한 이유 (0) 2022.04.03 스레드 생명 주기 + 우선순위 (0) 2022.04.03 쓰레드 제어, 쓰레드 종료 (0) 2022.04.03 CreateThread,멀티 쓰레드 + (쓰레드가 필요한 이유) (0) 2022.04.03 Process란? (0) 2022.04.02