Thread-safety

강병우·2023년 11월 6일
0

병렬프로그래밍

목록 보기
19/24

어떤 코드가 다수의 스레드에 의해 아무 문제 없이 실행되는 것을 Thread-safe하다고 할 수 있다.

영어 텍스트로 구성되어 있는 파일을 다수의 스레드를 사용하여 토크나이즈하는 상황을 가정해보자. 텍스트에 공백문자, 탭키 등을 통해 텍스트들을 구분해본다.

가장 심플한 문제는 각 라인에 접근할 때 세마포어를 사용하는 것이다. 각 스레드별로 line을 읽어내고 strtok라는 함수를 통해 토크나이즈할 수 있다. strtoc에 대한 설명은 다음과 같다.

string은 전체 텍스트, separators는 토크나이즈의 기준이 되겠다. 예를 들자면 공백문자나 탭키 등을 여기에 쓰면 이것들을 기준으로 텍스트를 나누게 된다. 나눌 때마다 이 토큰들은 캐시에 복사되어 저장된다.

토크나이즈하는 소스코드이다. 모든 행이 끝날 때까지 토크나이즈을 한다.

이 텍스트들을 토크나이즈한다면, 다음과 같은 결과를 얻을 수 있다.

하지만 중간에 Thread1이 이상하게 출력한다. strtok에서 하나의 콜에서 캐싱을 하게 되어 있다. 캐시 String이 공유되어 있는 상황에서, 스레드1의 작업이 끝나지 않았는데 스레드 0가 먼저 끝나, 스레드1의 String에 접근하여 Overwritten해버렸기 때문이다. 이는 Strtok가 Not thread-safe하기 때문이다.

정리

C Library 함수들은 thread-safte하지 않다. C Standard를 사용하기 전에 위 사진처럼 수정해서 사용해야 한다.

Thread는 경량화된 프로세스들로, pthread 프로그램에서는 모든 스레드들이 전역 변수에 접근한다. 또한 특정한 변수들만 지역 변수로 private하게 사용한다.

여러 개의 스레드가 있고 공유 변수에 접근하려 할 때, Race condition이 발생할 수 있다.

Critical Section을 통해 공유리소스를 하나의 스레드에서만 업데이트할 수 있도록 블록 단위의 코드들을 보호한다.

Busy Waiting은 Flag 변수와 While loop를 통해 Critical Section을 구현한다. 이는 CPU 자원을 낭비하게 된다.

Mutex는 하나의 스레드만 Critical Section에 진입할 수 있도록 한다.

Semaphore은 여러 개의 스레드를 관리할 때 쓰인다(자세한 건 세마포어 필기를 보자)

Barrier은 특정 위치에 모든 스레드가 도착할 때까지 기다리고 모두 도착했을 때 실행되도록 한다.

Read-Write Lock은 다수의 스레드가 하나의 공유변수에 읽기-쓰기에 접근하려 할 때 사용되는 Lock방식이다.

일부 C 함수들은 Thread Programming에 사용될 수 있지만, 어떤 함수는 Not thread safe하기 때문에 주의해야 한다

0개의 댓글