런타임 라이브러리의 스레드 안전성
런타임 라이브러리의 스레드 안전성 (Thread-safety of the runtime library)
멀티스레드 프로그램에서 GNU Fortran(libgfortran)을 쓸 때 어떤 기능들이 스레드 안전하지 않을 수 있는지, 그래서 사용자가 어떤 책임을 져야 하는지 설명해요. 환경 변수 접근, 셸 명령 실행, 그리고 로케일(LC_NUMERIC) 의존 형식화 I/O를 중심으로 주의점을 정리했어요.
출처: Thread-safety of the runtime library (The GNU Fortran Compiler)
본문
GNU Fortran은 여러 스레드가 있는 프로그램에서 쓸 수 있어요. 예를 들어 OpenMP를 쓰거나, ISO_C_BINDING 기능을 통해 OS 스레드 처리 함수를 호출하거나, GNU Fortran으로 컴파일한 라이브러리 코드를 멀티스레드 프로그램에서 호출하는 방식이지요.
GNU Fortran 런타임 라이브러리인 libgfortran은 다음 예외 사항을 제외하고 여러 스레드에서 동시에 호출되는 것을 지원해요.
라이브러리 초기화 중에는 C의 getenv 함수가 사용되는데, 이 함수는 스레드 안전할 필요가 없어요. 마찬가지로 GET_ENVIRONMENT_VARIABLE과 GETENV 내장 함수를 구현하는 데도 getenv 함수가 사용돼요. 이런 동작들이 일어나는 동안 환경이 동시에 갱신되지 않도록 하는 것은 사용자의 책임이에요.
EXECUTE_COMMAND_LINE과 SYSTEM 내장 함수는 system 함수로 구현되는데, 이 함수는 스레드 안전할 필요가 없어요. system이 동시에 호출되지 않도록 하는 것은 사용자의 책임이에요.
스레드 안전한 POSIX 함수를 지원하지 않는 플랫폼에서는 추가 기능이 스레드 안전하지 않을 수 있어요. 자세한 내용은 운영체제 문서를 참조해야 해요.
GNU Fortran 런타임 라이브러리는 strtod나 snprintf 같은 로케일 의존 C 라이브러리 함수를 여러 개 사용해요. setlocale로 로케일을 설정하는 로케일 인식 프로그램에서 올바르게 동작하기 위해, 형식화된 READ 또는 WRITE 문을 실행하는 동안 로케일은 기본 "C" 로케일로 재설정돼요. POSIX 2008의 스레드별 로케일 함수(예: newlocale, uselocale, freelocale)를 지원하는 타깃에서는 이 함수들이 사용되므로, setlocale로 설정된 전역 로케일이나 다른 스레드의 스레드별 로케일은 영향을 받지 않아요. 그러나 이 기능이 없는 타깃에서는 형식화 I/O 중에 전역 LC_NUMERIC 로케일이 "C"로 설정돼요. 따라서 그런 타깃에서는 Fortran 형식화 I/O 작업이 진행되는 동안 다른 스레드에서 setlocale을 동시에 호출하는 것이 안전하지 않아요. 또한 다른 스레드에서 LC_NUMERIC 로케일에 의존하는 작업을 하는 경우, 다른 스레드에서 형식화 I/O 작업이 진행 중이면 제대로 동작하지 않을 수 있어요.
더 알아보기
- Runtime Options — 런타임 동작 옵션
- EXECUTE_COMMAND_LINE — 셸 명령 실행 내장 함수
- GET_ENVIRONMENT_VARIABLE — 환경 변수 읽기 내장 함수