Search

<pthread.h>

Created
2021/07/20
tag
C
Philosophers
pthread.h
thread
attr
mutex

Subjects

β€’
<pthread.h>μ—λŠ” pthreadλ₯Ό λ‹€λ£° 수 μžˆλŠ” ν•¨μˆ˜λ“€μ΄ λ‹€μˆ˜ μ‘΄μž¬ν•œλ‹€. pthread의 생성 및 μ†Œλ©Έ, Data Race 방지λ₯Ό μœ„ν•œ mutex λ“±μ˜ μ‘°μž‘μ„ ν•  수 μžˆλ‹€. μ“°λ ˆλ“œμ— λŒ€ν•œ λ³„λ„μ˜ μ„€μ • μ—†μ΄λŠ” User-Level μ“°λ ˆλ“œλ₯Ό μ΄μš©ν•˜κ²Œ λ˜μ§€λ§Œ, μ“°λ ˆλ“œμ˜ 속성 섀정을 톡해 Kernel-Level μ“°λ ˆλ“œλ‘œ μ΄μš©ν•˜λŠ” 것도 κ°€λŠ₯ν•˜λ‹€. 수 λ§Žμ€ ν•¨μˆ˜μ™€ μ •μ˜λœ 맀크둜 κ°’λ“€ μ€‘μ—μ„œλ„ pthread_create, pthread_join, pthread_detach와 같은 μ“°λ ˆλ“œμ˜ 생성 및 μ†Œλ©Έ ν•¨μˆ˜, pthread_mutex_init, pthread_mutex_destroy와 같은 mutex의 생성 및 μ†Œλ©Έ ν•¨μˆ˜, pthread_mutex_lock, pthread_mutex_unlockκ³Ό 같은 mutex의 잠금 ν•¨μˆ˜, 그리고 μ“°λ ˆλ“œμ˜ 속성 κ΄€λ ¨ ν•¨μˆ˜λ“€μ— λŒ€ν•΄μ„œλ§Œ κ°„λ‹¨νžˆ μ•Œμ•„λ³Ό 것이닀.

1. μ“°λ ˆλ“œ 속성

μ“°λ ˆλ“œ 속성 값은 μ•„λž˜μ— 주어진 ν•¨μˆ˜λ“€μ„ 톡해 μ΄ˆκΈ°ν™”ν•˜κ³  μ„€μ •ν•  수 μžˆλŠ”λ°, 맀뉴얼을 μ‚΄νŽ΄λ³΄λ©΄ 더 λ§Žμ€ μ„€μ • 값을 μ œμ–΄ν•  수 μžˆμœΌλ―€λ‘œ ν•„μš”ν•œ κ²½μš°μ—λŠ” λ°˜λ“œμ‹œ 맀뉴얼을 μ‚΄νŽ΄λ³΄λ„λ‘ ν•˜μž.

1) pthread_attr_init

ν•¨μˆ˜ μ›ν˜•

int pthread_attr_init(pthread_attr_t *);
C

ν•¨μˆ˜ 인자

μ“°λ ˆλ“œμ˜ 속성을 결정지을 pthread_attr_t의 μ£Όμ†Œλ₯Ό λ°›λŠ”λ‹€. ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œλŠ” 인자둜 받은 μ£Όμ†Œμ— pthread_attr_tλ₯Ό ν• λ‹Ήν•œλ‹€.

λ°˜ν™˜ κ°’

ν•¨μˆ˜ 호좜이 μ •μƒμ μœΌλ‘œ λ™μž‘ν–ˆλ‹€λ©΄ 0을 λ°˜ν™˜ν•˜κ³ , 그렇지 μ•ŠμœΌλ©΄ 0이 μ•„λ‹Œ 값을 λ°˜ν™˜ν•œλ‹€.

μ°Έκ³ 

pthread_attr_init으둜 이미 μ΄ˆκΈ°ν™” 된 pthread_attr_tλ₯Ό λ‹€μ‹œ 인자둜 λ„£μ–΄ ν˜ΈμΆœν•˜λŠ” ν–‰μœ„λŠ” Undefined Behavior이닀. λ˜ν•œ pthread_attr_init을 톡해 μ΄ˆκΈ°ν™”λœ pthread_attr_tλŠ” μ΄μš©μ„ λ§ˆμ³€μ„ λ•Œ λ°˜λ“œμ‹œ pthread_attr_destory의 호좜이 μš”κ΅¬λœλ‹€.
pthread_attr_init의 호좜둜 pthread_attr_t에 ν• λ‹Ήλœ 값은 μ†μ„±μ˜ κΈ°λ³Έ 값이닀. λ”°λΌμ„œ 속성을 μ΄μš©ν•˜κ³  μ‹Άλ‹€λ©΄ λ³„λ„λ‘œ 값에 λŒ€ν•œ 쑰정이 ν•„μš”ν•˜λ‹€. 이λ₯Ό μ§€μ›ν•˜λŠ” ν•¨μˆ˜λ“€μ€ 속성에 따라 마련이 λ˜μ–΄ μžˆμœΌλ‹ˆ 할당받은 pthread_attr_t의 μ£Όμ†Œλ₯Ό 인자둜 λ„˜κ²¨ 주기만 ν•˜λ©΄ λœλ‹€. ν•΄λ‹Ή ν•¨μˆ˜λ“€μ€ μ•„λž˜μ—μ„œ 닀룬닀.
pthread_attr_destory의 호좜이 λ˜μ—ˆλ‹€κ°€ pthread_attr_init을 ν˜ΈμΆœν•˜λŠ” 것은 μ•„λ¬΄λŸ° λ¬Έμ œκ°€ μ—†λ‹€.

2) pthread_attr_destory

ν•¨μˆ˜ μ›ν˜•

int pthread_attr_destroy(pthread_attr_t *);
C

ν•¨μˆ˜ 인자

기쑴에 pthread_attr_init으둜 μ΄ˆκΈ°ν™” 된 pthread_attr_t의 μ£Όμ†Œλ₯Ό 인자둜 λ°›λŠ”λ‹€.

λ°˜ν™˜ κ°’

ν•¨μˆ˜ 호좜이 μ •μƒμ μœΌλ‘œ λ™μž‘ν–ˆλ‹€λ©΄ 0을 λ°˜ν™˜ν•˜κ³ , 그렇지 μ•ŠμœΌλ©΄ 0이 μ•„λ‹Œ 값을 λ°˜ν™˜ν•œλ‹€.

μ°Έκ³ 

μ΄ˆκΈ°ν™” λ˜μ§€ μ•Šμ€ pthread_attr_tλ₯Ό pthread_attr_destroy에 μ΄μš©ν•˜λŠ” 것은 Undefined Behavior이닀.

3) pthread_attr_setdetachstate

ν•¨μˆ˜ μ›ν˜•

int pthread_attr_setdetachstate(pthread_attr_t *, int);
C

ν•¨μˆ˜ 인자

pthread_attr_init을 톡해 μ΄ˆκΈ°ν™” 된 pthread_attr_t의 μ£Όμ†Œλ₯Ό 인자둜 μ€€λ‹€. 생성할 μ“°λ ˆλ“œκ°€ μ–΄λ–€ μƒνƒœλ₯Ό κ°€μ§ˆμ§€λ₯Ό int νƒ€μž…μ˜ κ°’μœΌλ‘œ λͺ…μ‹œν•œλ‹€.
μ‚¬μš©ν•  수 μžˆλŠ” μƒνƒœ 값은 PTRHEAD_CREATE_JOINABLE, PTHREAD_CREATE_DETACHED이닀. 만일 pthread_attr_setdetachstate 호좜 없이 pthread_attr_tλ₯Ό μ΄μš©ν•˜λ©΄ 이 λ•Œμ˜ κΈ°λ³Έ 섀정은 PTHREAD_CREATE_JOINABLE이닀.

λ°˜ν™˜ κ°’

ν•¨μˆ˜ 호좜이 μ •μƒμ μœΌλ‘œ λ™μž‘ν–ˆλ‹€λ©΄ 0을 λ°˜ν™˜ν•˜κ³ , 그렇지 μ•ŠμœΌλ©΄ 0이 μ•„λ‹Œ 값을 λ°˜ν™˜ν•œλ‹€.

μ°Έκ³ 

User-Level 및 Kernel-Level μ“°λ ˆλ“œμ™€ 같은 μ“°λ ˆλ“œμ˜ μ‚¬μš©μ²˜μ— λ”°λ₯Έ λΆ„λ₯˜ 외에도 μ“°λ ˆλ“œκ°€ μ“°λ ˆλ“œ λ‚΄μ—μ„œ μ‚¬μš©ν•œ μžμ›μ— λŒ€ν•œ 관점에 λ”°λΌμ„œλ„ λΆ„λ₯˜ν•  수 μžˆλ‹€. 기본적으둜 μ“°λ ˆλ“œλŠ” μƒνƒœμ— λ”°λ₯Έ Joinable μ“°λ ˆλ“œμ™€ Detached μ“°λ ˆλ“œλ‘œ λ‚˜λ‰œλ‹€.
Joinable μ“°λ ˆλ“œμ˜ κ²½μš°μ—λŠ” μ“°λ ˆλ“œμ˜ μ’…λ£Œ μ‹œμ— λ°˜λ“œμ‹œ pthread_join ν•¨μˆ˜λ₯Ό μ΄μš©ν•˜μ—¬ μžμ›μ„ λ°˜ν™˜ν•΄μ€˜μ•Ό ν•˜λ©°, 이λ₯Ό 톡해 μ“°λ ˆλ“œκ°€ μ’…λ£Œλ˜μ—ˆμŒμ„ λ‹€λ₯Έ μ“°λ ˆλ“œμ— μ•Œλ¦΄ λ•Œ μ΄μš©λœλ‹€. Joinable μ“°λ ˆλ“œμ˜ κ²½μš°μ—λŠ” wait ν˜Ήμ€ waitpid ν•¨μˆ˜μ˜ λ§₯락과 λΉ„μŠ·ν•˜λ‹€.
λ°˜λŒ€λ‘œ Detached μ“°λ ˆλ“œλŠ” μ“°λ ˆλ“œμ˜ μ’…λ£Œ μ‹œμ— 슀슀둜 μžμ›μ„ λ°˜ν™˜ν•΄μ£Όμ–΄ λ³„λ„μ˜ pthread_join이 μš”κ΅¬λ˜μ§€ μ•ŠλŠ”λ‹€. λ”°λΌμ„œ λ‹€λ₯Έ μ“°λ ˆλ“œμ™€ λ…λ¦½μ μœΌλ‘œ λ™μž‘ν•˜λŠ” κ²½μš°μ— μ΄μš©λœλ‹€.

4) pthread_attr_getdetachstate

ν•¨μˆ˜ μ›ν˜•

int pthread_attr_getdetachstate(const pthread_attr_t *, int *);
C

ν•¨μˆ˜ 인자

ν™•μΈν•˜κ³ μž ν•˜λŠ” pthread_attr_t의 μ£Όμ†Œλ₯Ό λ°›λŠ”λ‹€. pthread_attr_t에 기둝된 μ“°λ ˆλ“œμ˜ μƒνƒœ μ„€μ • 값을 확인할 수 μžˆλ„λ‘ int νƒ€μž…μ˜ μ£Όμ†Œλ₯Ό λ°›μ•„ μ—­μ°Έμ‘°ν•˜μ—¬ μ„€μ • 값을 μ €μž₯ν•œλ‹€.
κΈ°λ‘λ˜λŠ” 값은 μƒνƒœ 맀크둜 값인 PTHREAD_CREATE_JOINABLE ν˜Ήμ€ PTHREAD_CREATE_DETACHED이닀.

λ°˜ν™˜ κ°’

ν•¨μˆ˜ 호좜이 μ •μƒμ μœΌλ‘œ λ™μž‘ν–ˆλ‹€λ©΄ 0을 λ°˜ν™˜ν•˜κ³ , 그렇지 μ•ŠμœΌλ©΄ 0이 μ•„λ‹Œ 값을 λ°˜ν™˜ν•œλ‹€.

5) pthread_attr_setscope

ν•¨μˆ˜ μ›ν˜•

int pthread_attr_setscope(pthread_attr_t *, int);
C

ν•¨μˆ˜ 인자

pthread_attr_init을 톡해 μ΄ˆκΈ°ν™” 된 pthread_attr_t의 μ£Όμ†Œλ₯Ό 인자둜 μ€€λ‹€. 생성할 μ“°λ ˆλ“œκ°€ μ–΄λ–€ λ²”μœ„λ₯Ό κ°€μ§ˆμ§€λ₯Ό int νƒ€μž…μ˜ κ°’μœΌλ‘œ λͺ…μ‹œν•œλ‹€.
μ‚¬μš©ν•  수 μžˆλŠ” μƒνƒœ 값은 PTRHEAD_SCOPE_SYSTEM, PTHREAD_SCOPE_PROCESS이닀. 만일 pthread_attr_setscope 호좜 없이 pthread_attr_tλ₯Ό μ΄μš©ν•˜λ©΄ 이 λ•Œμ˜ κΈ°λ³Έ 섀정은 PTHREAD_SCOPE_SYSTEM이닀.

λ°˜ν™˜ κ°’

ν•¨μˆ˜ 호좜이 μ •μƒμ μœΌλ‘œ λ™μž‘ν–ˆλ‹€λ©΄ 0을 λ°˜ν™˜ν•˜κ³ , 그렇지 μ•ŠμœΌλ©΄ 0이 μ•„λ‹Œ 값을 λ°˜ν™˜ν•œλ‹€.

μ°Έκ³ 

Critical Section에 μ ‘κ·Όν•˜κΈ° μœ„ν•΄ LOCK을 μ–»μœΌλ €κ³  κ²½μŸν•˜λŠ” μƒνƒœλ₯Ό Contention이라고 ν•˜λŠ”λ°, 이 λ•Œ Contention의 λ²”μœ„λ₯Ό μ„€μ •ν•  λ•Œ pthread_attr_setscopeκ°€ μ΄μš©λœλ‹€. 기본적으둜 μ“°λ ˆλ“œμ˜ 생성은 User-Level μ“°λ ˆλ“œμ΄λ©°, Kernel-Level μ“°λ ˆλ“œμ˜ 생성은 μ‹œμŠ€ν…œμ— 달렀 μžˆλ‹€. μ—¬κΈ°μ„œ λ²”μœ„μ˜ 섀정이 κΈ°μ—¬ν•˜λŠ” λ°”λŠ” μ’…λ₯˜μ— λ”°λ₯Έ μ“°λ ˆλ“œ 생성이 μ•„λ‹ˆλΌ, User-Level μ“°λ ˆλ“œκ°€ Kernel-Level μ“°λ ˆλ“œμ— μ–΄λ–»κ²Œ Mapping 될지에 λ”°λ₯Έ Contention의 섀정이닀.
PTHREAD_SCOPE_SYSTEM으둜 μ„€μ •λœ μ“°λ ˆλ“œλ“€μ€ μ‹œμŠ€ν…œ μƒμ—μ„œ Globalν•˜κ²Œ Contention을 κ°–κΈ° λ•Œλ¬Έμ—, 각 μ“°λ ˆλ“œλ“€μ€ ν•˜λ‚˜μ˜ Kernel-Level μ“°λ ˆλ“œλ‘œ Mapping λ˜λŠ” κ²ƒμœΌλ‘œ μ΄ν•΄λœλ‹€. 주둜 One-to-Oneμ—μ„œ PTHREAD_SCOPE_SYSTEM으둜 μ„€μ •ν•˜μ—¬ μ΄μš©ν•œλ‹€.
PTHREAD_SCOPE_PROCESS둜 μ„€μ •λœ μ“°λ ˆλ“œλ“€μ€ ν”„λ‘œμ„ΈμŠ€ μƒμ—μ„œ Localν•˜κ²Œ Contention을 κ°–κΈ° λ•Œλ¬Έμ—, μ—¬λŸ¬ μ“°λ ˆλ“œλ“€μ΄ ν•˜λ‚˜μ˜ Kernel-Level μ“°λ ˆλ“œλ₯Ό κ³΅μœ ν•˜λŠ” κ²ƒμœΌλ‘œ μ΄ν•΄λœλ‹€. 주둜 Many-to-Oneμ—μ„œ PTHREAD_SCOPE_PROCESS둜 μ„€μ •ν•˜μ—¬ μ΄μš©ν•œλ‹€.
Many-to-Manyμ—μ„œλŠ” PTHREAD_SCOPE_PROCESS ν˜Ήμ€ PTHREAD_SCOPE_SYSTEM μ–΄λ–€ 것을 μ‚¬μš©ν•΄λ„ λ¬΄λ°©ν•˜λ‹€.
μœ„ κ·Έλ¦Όμ—μ„œ μ œμ‹œλœ Light Weight Process (LWP)λŠ” User-Level μ“°λ ˆλ“œλ₯Ό Kernel-Level μ“°λ ˆλ“œμ— Mapping ν•˜κΈ° μœ„ν•œ μΌμ’…μ˜ μΈν„°νŽ˜μ΄μŠ€μ΄κ³ , Process Contention Scope와 System Contention Scopeλ₯Ό μ˜λ―Έν•˜λŠ” 말이 각각 PCS와 SCS이닀.
μ‚¬μš©ν•˜κ³  μžˆλŠ” μ“°λ ˆλ“œ λΌμ΄λΈŒλŸ¬λ¦¬μ—μ„œ TiT_{i}둜 ν‘œκΈ°λœ User-Level μ“°λ ˆλ“œλ₯Ό LWPλΌλŠ” μŠ€μΌ€μ€„λ§ λ‹¨μœ„λ‘œ λ§Œλ“€μ–΄ λ‚΄κ³ , 이듀이 Kernel-Level μ“°λ ˆλ“œμ˜ Mapping λ˜μ–΄ 곧 μš΄μ˜μ²΄μ œμ— μ˜ν•΄ μŠ€μΌ€μ€„λ§ λœλ‹€. 즉, PCSλŠ” LWP의 점유λ₯Ό μœ„ν•œ Contention을 벌이고, SCSλŠ” 각각의 μ“°λ ˆλ“œκ°€ LWPκ°€ 됨에 따라 Kernel-Level μ“°λ ˆλ“œκ°€ μŠ€μΌ€μ€„λ§ 될 λ•Œ Contention이 λ²Œμ–΄μ§€λŠ” 것을 λ³Ό 수 μžˆλ‹€.

6) pthread_attr_getscope

ν•¨μˆ˜ μ›ν˜•

int pthread_attr_getscope(const pthread_attr_t *restrict, int *restrict);
C

ν•¨μˆ˜ 인자

ν™•μΈν•˜κ³ μž ν•˜λŠ” pthread_attr_t의 μ£Όμ†Œλ₯Ό λ°›λŠ”λ‹€. pthread_attr_t에 기둝된 μ“°λ ˆλ“œμ˜ λ²”μœ„ μ„€μ • 값을 확인할 수 μžˆλ„λ‘ int νƒ€μž…μ˜ μ£Όμ†Œλ₯Ό λ°›μ•„ μ—­μ°Έμ‘°ν•˜μ—¬ μ„€μ • 값을 μ €μž₯ν•œλ‹€.
κΈ°λ‘λ˜λŠ” 값은 λ²”μœ„ 맀크둜 값인 PTHREAD_SCOPE_SYSTEM ν˜Ήμ€ PTHREAD_SCOPE_PROCESS이닀.

λ°˜ν™˜ κ°’

ν•¨μˆ˜ 호좜이 μ •μƒμ μœΌλ‘œ λ™μž‘ν–ˆλ‹€λ©΄ 0을 λ°˜ν™˜ν•˜κ³ , 그렇지 μ•ŠμœΌλ©΄ 0이 μ•„λ‹Œ 값을 λ°˜ν™˜ν•œλ‹€.

7) pthread_attr_setstacksize

ν•¨μˆ˜ μ›ν˜•

int pthread_attr_setstacksize(pthread_attr_t *, size_t);
C

ν•¨μˆ˜ 인자

pthread_attr_init을 톡해 μ΄ˆκΈ°ν™” 된 pthread_attr_t의 μ£Όμ†Œλ₯Ό 인자둜 μ€€λ‹€. 생성할 μ“°λ ˆλ“œκ°€ λͺ‡ λ°”μ΄νŠΈμ˜ Stack을 μ΄μš©ν• μ§€, κ·Έ 크기λ₯Ό size_t νƒ€μž…μ˜ κ°’μœΌλ‘œ λͺ…μ‹œν•œλ‹€.

λ°˜ν™˜ κ°’

ν•¨μˆ˜ 호좜이 μ •μƒμ μœΌλ‘œ λ™μž‘ν–ˆλ‹€λ©΄ 0을 λ°˜ν™˜ν•˜κ³ , 그렇지 μ•ŠμœΌλ©΄ 0이 μ•„λ‹Œ 값을 λ°˜ν™˜ν•œλ‹€.

μ°Έκ³ 

만일 인자둜 넣은 값이 <limits.h>에 μ •μ˜λœ PTHREAD_STACK_MIN 보닀 μž‘μ€ κ°’μœΌλ‘œ μ„€μ •λ˜λ©΄ errnoλŠ” EINVAL이 λœλ‹€. λͺ‡ μ‹œμŠ€ν…œμ—μ„œλŠ” νŽ˜μ΄μ§€ λ‹¨μœ„ κ°’μ˜ λ°°μˆ˜κ°€ μ•„λ‹ˆλΌλ©΄ errnoλ₯Ό EINVAL둜 λ§Œλ“ λ‹€. 이와 같은 μ‹œμŠ€ν…œμ„ μ œμ™Έν•œ λ‚˜λ¨Έμ§€ μ‹œμŠ€ν…œμ—μ„œλŠ” 인자둜 넣은 값이 νŽ˜μ΄μ§€ λ‹¨μœ„ 값에 λ§žμ§€ μ•Šλ‹€λ©΄ ν• λ‹Ήν•  수 μžˆλŠ” κ°’ 쀑 인자 값보닀 큰 μ΅œμ†Œ 값을 ν• λ‹Ήν•œλ‹€.
Mac OS Xμ—μ„œλŠ” λ°˜λ“œμ‹œ νŽ˜μ΄μ§€ λ‹¨μœ„ κ°’μ˜ 배수둜 Stack 크기λ₯Ό μ •ν•΄μ•Ό ν•œλ‹€.

8) pthread_attr_getstacksize

ν•¨μˆ˜ μ›ν˜•

int pthread_attr_getstacksize(const pthread_attr_t *restrict, size_t *restrict);
C

ν•¨μˆ˜ 인자

ν™•μΈν•˜κ³ μž ν•˜λŠ” pthread_attr_t의 μ£Όμ†Œλ₯Ό λ°›λŠ”λ‹€. pthread_attr_t에 기둝된 μ“°λ ˆλ“œμ˜ Stack 크기 값을 확인할 수 μžˆλ„λ‘ size_t νƒ€μž…μ˜ μ£Όμ†Œλ₯Ό λ°›μ•„ μ—­μ°Έμ‘°ν•˜μ—¬ μ„€μ • 값을 μ €μž₯ν•œλ‹€.

λ°˜ν™˜ κ°’

ν•¨μˆ˜ 호좜이 μ •μƒμ μœΌλ‘œ λ™μž‘ν–ˆλ‹€λ©΄ 0을 λ°˜ν™˜ν•˜κ³ , 그렇지 μ•ŠμœΌλ©΄ 0이 μ•„λ‹Œ 값을 λ°˜ν™˜ν•œλ‹€.

2. μ“°λ ˆλ“œ

1) pthread_create

ν•¨μˆ˜ μ›ν˜•

int pthread_create(pthread_t *restrict, const pthread_attr_t *restrict, void *(*)(void*), void *restrict);
C

ν•¨μˆ˜ 인자

User-Level μ“°λ ˆλ“œκ°€ 생성될 pthread_t νƒ€μž…μ˜ μ£Όμ†Œ κ°’κ³Ό User-Level μ“°λ ˆλ“œμ˜ 속성 값이 μ‘΄μž¬ν•˜λŠ” pthread_attr_t의 μ£Όμ†Œ 값을 인자둜 λ°›λŠ”λ‹€. 속성 값을 μ΄μš©ν•˜μ—¬ 문제 없이 μ“°λ ˆλ“œκ°€ μƒμ„±λ˜μ—ˆλ‹€λ©΄, μ“°λ ˆλ“œμ˜ μž‘μ—…μ€ νŠΉμ • ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•˜λ©΄μ„œ μˆ˜ν–‰λœλ‹€. λ”°λΌμ„œ μž‘μ—…μ„ μˆ˜ν–‰ν•˜κΈ° μœ„ν•΄μ„œ μ„Έ 번째 인자둜 ν•¨μˆ˜ 포인터λ₯Ό μ΄μš©ν•˜λ©°, ν•΄λ‹Ή ν•¨μˆ˜μ—μ„œ μ‚¬μš©ν•  인자λ₯Ό λ„€ 번째 인자 κ°’μœΌλ‘œ λͺ…μ‹œν•œλ‹€.

λ°˜ν™˜ κ°’

ν•¨μˆ˜ 호좜이 μ •μƒμ μœΌλ‘œ λ™μž‘ν–ˆλ‹€λ©΄ 0을 λ°˜ν™˜ν•˜κ³ , 그렇지 μ•ŠμœΌλ©΄ 0이 μ•„λ‹Œ 값을 λ°˜ν™˜ν•œλ‹€.

μ°Έκ³ 

λ³„λ„μ˜ 속성 값을 μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄ 두 번째 인자λ₯Ό NULL둜 μ£Όλ©΄ 되고, κΈ°λ³Έ μ†μ„±μœΌλ‘œ μ“°λ ˆλ“œκ°€ μƒμ„±λœλ‹€. λ˜ν•œ μ“°λ ˆλ“œ λ‚΄μ—μ„œ μˆ˜ν–‰ν•  μž‘μ—…μ— λŒ€ν•΄μ„œλŠ” Non-Nullableμ΄λ―€λ‘œ λ°˜λ“œμ‹œ 기재 λ˜μ–΄μ•Ό ν•œλ‹€. ν•΄λ‹Ή μž‘μ—…μ—μ„œ μ‚¬μš©ν•  μΈμžλŠ” Nullableμ΄λ―€λ‘œ 만일 μž‘μ—… λ‚΄μ—μ„œ λ³„λ„μ˜ 인자λ₯Ό μš”κ΅¬ν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄ pthread_create의 λ„€ 번째 인자 μ—­μ‹œ NULL을 μ£Όλ©΄ λœλ‹€.
μƒμ„±λœ μ“°λ ˆλ“œμ—μ„œ μ‚¬μš©ν•  μΈμžλŠ” 라이브러리 κ΅¬ν˜„μ— 따라 κ°€λ³€ 인자λ₯Ό ν™œμš©ν•˜μ—¬ μ—¬λŸΏ 받을 μˆ˜λ„ μžˆμ§€λ§Œ, <pthread.h>μ—μ„œλŠ” void *단일 인자λ₯Ό μ‚¬μš©ν•˜κΈ° λ•Œλ¬Έμ— μ“°λ ˆλ“œ λ‚΄μ—μ„œ μ—¬λŸ¬ μΈμžκ°€ ν•„μš”ν•œ 경우 λ³„λ„μ˜ ꡬ쑰체λ₯Ό μ •μ˜ν•˜μ—¬ μΈμžλ“€μ„ Wrapping μž‘μ—…μ΄ μš”κ΅¬λœλ‹€. λ˜ν•œ μ“°λ ˆλ“œλ‘œ μ‹€ν–‰ν•  μž‘μ—…μ€ ν•¨μˆ˜ ν¬μΈν„°λ‘œ λͺ…μ‹œλ¨μ— 따라 void *λ₯Ό λ°˜ν™˜ν•˜κ³  void *λ₯Ό 인자둜 λ°›λŠ” μ›ν˜•μœΌλ‘œ μ„ μ–Έ 및 μ •μ˜λ˜μ–΄μ•Ό ν•œλ‹€. ν•¨μˆ˜ ν¬μΈν„°μ˜ ν˜• λ³€ν™˜μ„ μ΄μš©ν•˜λŠ” 방법도 μžˆκ² μ§€λ§Œ, ꢌμž₯λ˜μ§€ μ•ŠλŠ”λ‹€.
μ“°λ ˆλ“œμ—μ„œ μ‹€ν–‰ν•  μž‘μ—…μ˜ 경우 void * λ°˜ν™˜ νƒ€μž…μΈ 것을 λ³Ό 수 μžˆλŠ”λ°, PTHREAD_CREATE_JOINABLE둜 μ„€μ •λœ μ“°λ ˆλ“œμ˜ κ²½μš°μ—λ§Œ void * λ°˜ν™˜ 값을 μ΄μš©ν•  수 μžˆλ‹€. 즉, PTHREAD_CRAETE_DETACHED의 κ²½μš°μ—λŠ” 독립적인 μ“°λ ˆλ“œλ‘œ κ°„μ£Όν•˜μ—¬ μ’…λ£Œ μ¦‰μ‹œ μžμ›μ„ λ°˜ν™˜ν•˜λ„λ‘ λ˜μ–΄ μžˆμœΌλ―€λ‘œ λ°˜ν™˜ 값을 μ΄μš©ν•˜λŠ” 것이 λΆˆκ°€λŠ₯ν•˜λ‹€.
Joinable μ“°λ ˆλ“œμ˜ 경우, λ°˜ν™˜λœ 값은 pthread_join을 톡해 λ„˜κ²¨ λ°›μ•„μ„œ ν™œμš©ν•  수 μžˆλ‹€. μ“°λ ˆλ“œ λ‚΄μ—μ„œ ν•¨μˆ˜ 호좜이 λ³΅μž‘ν•˜μ—¬ ν˜ΈμΆœν•œ ν•¨μˆ˜ λ‚΄μ—μ„œ Fallback을 μˆ˜ν–‰ν•΄μ•Ό ν•˜λŠ” 경우, λ°˜ν™˜μ„ ν†΅ν•΄μ„œ pthread_join에 값을 λ„˜κΈ°λŠ” 방법 외에도 pthread_exit을 톡해 pthread_join이 λ°˜ν™˜ 값을 ν™œμš©ν•˜λ„λ‘ ν•  수 μžˆλ‹€.
μ œμ‹œλœ ν•¨μˆ˜λ“€μ€ μ•„λž˜μ—μ„œ 닀룬닀.

2) pthread_join

ν•¨μˆ˜ μ›ν˜•

int pthread_join(pthread_t, void **);
C

ν•¨μˆ˜ 인자

μ–΄λ–€ μ“°λ ˆλ“œμ˜ μž‘μ—…μ΄ μ’…λ£Œλ  λ•ŒκΉŒμ§€ λŒ€κΈ°ν• μ§€ κ΅¬λΆ„ν•˜κΈ° μœ„ν•΄ pthread_t νƒ€μž…μ˜ ID 값을 첫 번째 인자둜 λ°›λŠ”λ‹€. 이 λ•Œ ν•΄λ‹Ή μ“°λ ˆλ“œμ˜ μž‘μ—…μ΄ μ’…λ£Œλ˜λ©΄ μžμ›μ„ λͺ¨λ‘ νšŒμˆ˜ν•˜λ©΄μ„œ μ“°λ ˆλ“œκ°€ λ°˜ν™˜ν•œ μ£Όμ†Œ 값을 ν¬μΈν„°λ‘œ λ°›μ•„ 올 수 μžˆλŠ”λ° 이λ₯Ό 이쀑 ν¬μΈν„°λ‘œ 된 두 번째 인자λ₯Ό 톡해 λ°›μ•„μ˜¨λ‹€.
pthread_tλŠ” μ‹œμŠ€ν…œμ— 따라 μ •μˆ˜ 값일 μˆ˜λ„ 있고 그렇지 μ•Šμ„ μˆ˜λ„ μžˆλ‹€. Mac OS Xμ—μ„œλŠ” pthread_tκ°€ ꡬ쑰체둜 λ˜μ–΄ μžˆλ‹€. 이 λ•Œ pthread_tκ°€ μ–΄λ–€ νƒ€μž…μœΌλ‘œ μ •μ˜λ˜μ–΄ μžˆλ“  간에 pthread_tλ₯Ό ID κ°’μœΌλ‘œ μ‚¬μš©ν•  수 μžˆλŠ”λ°, μ΄λŠ” λ©”λͺ¨λ¦¬ μžμ²΄μ— μ“°μ΄λŠ” 값이 λ™μΌν•œ ν”„λ‘œμ„ΈμŠ€ λ‚΄μ˜ 각 μ“°λ ˆλ“œμ—μ„œλŠ” κ³ μœ ν•œ κ°’μœΌλ‘œ ν• λ‹Ήλ˜κΈ° λ•Œλ¬Έμ΄λ‹€. λ¬Όλ‘  μ—„λ°€νžˆ 따지면 μ΄λŠ” μ“°λ ˆλ“œλ₯Ό κ΅¬λΆ„ν•˜λŠ” κ³ μœ ν•œ 값일 뿐 gettidλΌλŠ” ν•¨μˆ˜λ‘œ 얻을 수 μžˆλŠ” μš΄μ˜μ²΄μ œμ—μ„œμ˜ μ“°λ ˆλ“œ IDμ™€λŠ” λ‹€λ₯΄λ‹€.

λ°˜ν™˜ κ°’

ν•¨μˆ˜ 호좜이 μ •μƒμ μœΌλ‘œ λ™μž‘ν–ˆλ‹€λ©΄ 0을 λ°˜ν™˜ν•˜κ³ , 그렇지 μ•ŠμœΌλ©΄ 0이 μ•„λ‹Œ 값을 λ°˜ν™˜ν•œλ‹€.

μ°Έκ³ 

pthread_join은 μž‘μ—…μ΄ μ™„λ£Œλ  λ•ŒκΉŒμ§€ κΈ°λ‹€λ Έλ‹€κ°€ μžμ›μ„ νšŒμˆ˜ν•œλ‹€λŠ” κ°œλ…μ—μ„œ wait 및 waitpid와 λΉ„μŠ·ν•˜λ‹€. <pthread.h>의 μ“°λ ˆλ“œλŠ” Joinableκ³Ό Detached둜 λ‚˜λ‰˜λŠ”λ° pthread_join은 Joinable μ“°λ ˆλ“œμ˜ μ’…λ£ŒκΉŒμ§€ λŒ€κΈ°ν•˜κ³  이에 λŒ€ν•œ μžμ›μ„ νšŒμˆ˜ν•  λ•Œ μ΄μš©λœλ‹€. λ³„λ„λ‘œ μ“°λ ˆλ“œμ˜ 속성 값을 μ§€μ •ν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄ Joinable μ“°λ ˆλ“œλ‘œ μƒμ„±λ˜λ―€λ‘œ pthread_join의 호좜이 ν•„μˆ˜μ μœΌλ‘œ μš”κ΅¬λœλ‹€. 이 λ•Œ Detached μ“°λ ˆλ“œμ— λŒ€ν•΄μ„œλŠ” pthread_join이 μ •μƒμ μœΌλ‘œ μž‘λ™ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— λ°˜λ“œμ‹œ Joinable μ“°λ ˆλ“œμ— λŒ€ν•΄μ„œ pthread_join을 μ΄μš©ν•  수 μžˆλ„λ‘ ν•΄μ•Ό ν•œλ‹€.
λ˜ν•œ Joinable μ“°λ ˆλ“œλŠ” λ‹€λ₯Έ μ“°λ ˆλ“œμ™€ ꡬ뢄지어 λ…λ¦½μ μœΌλ‘œ μ‹€ν–‰λ˜λŠ” Detached μ“°λ ˆλ“œμ™€λŠ” 차이가 있기 λ•Œλ¬Έμ—, pthread_join을 톡해 ν•΄λ‹Ή μ“°λ ˆλ“œκ°€ λ°˜ν™˜ν•˜λŠ” 값을 λ°›μ•„ ν™œμš©ν•˜λŠ” 것이 κ°€λŠ₯ν•˜λ‹€. 만일 Joinable μ“°λ ˆλ“œκ°€ pthread_cancel에 μ˜ν•΄ μ€‘μ§€λ˜λ©΄, pthread_join으둜 얻을 수 μžˆλŠ” μ“°λ ˆλ“œμ˜ λ°˜ν™˜ 값은 PTHREAD_CANCELEDλΌλŠ” 맀크둜 값이 λœλ‹€.
Joinable μ“°λ ˆλ“œμ˜ λ°˜ν™˜ 값은 두 번째 인자λ₯Ό 톡해 μ΄μš©ν•  수 μžˆλŠ”λ°, λ°˜ν™˜ 값을 받더라도 μ΄μš©ν•˜μ§€ μ•Šμ„ 것이라면 두 번째 인자λ₯Ό NULL둜 두고 pthread_join을 ν˜ΈμΆœν•˜λ©΄ λœλ‹€.
두 번째 μΈμžκ°€ 이쀑 포인터인 μ΄μœ λŠ” μ“°λ ˆλ“œ μ‹€ν–‰ μ‹œ λ°˜ν™˜ 값이 단일 ν¬μΈν„°λΌλŠ” 점을 톡해 μœ μΆ”ν•  수 μžˆλ‹€. 단일 ν¬μΈν„°μ˜ λ°˜ν™˜μ„ λ‹€λ₯Έ λΈ”λ‘μ˜ 단일 포인터에 ν• λ‹Ήν•˜κΈ° μœ„ν•΄μ„  μ£Όμ†Œμ˜ Value둜 ν• λ‹Ήν•˜λŠ” 것이 μ•„λ‹ˆλΌ μ£Όμ†Œμ˜ Referenceλ₯Ό ν†΅ν•œ 할당이 μš”κ΅¬λœλ‹€.

3) pthread_detach

ν•¨μˆ˜ μ›ν˜•

int pthread_detach(pthread_t);
C

ν•¨μˆ˜ 인자

Detached둜 μƒμ„±λœ μ“°λ ˆλ“œμ— λŒ€ν•΄ 독립적인 μ“°λ ˆλ“œμž„μ„ λͺ…μ‹œν•˜κΈ° μœ„ν•΄ pthread_detachλ₯Ό μ΄μš©ν•œλ‹€. λ”°λΌμ„œ ν•΄λ‹Ή μ“°λ ˆλ“œλ₯Ό 인식할 수 μžˆλŠ” pthread_t νƒ€μž…μ˜ IDλ₯Ό 인자둜 λ°›λŠ”λ‹€.

λ°˜ν™˜ κ°’

ν•¨μˆ˜ 호좜이 μ •μƒμ μœΌλ‘œ λ™μž‘ν–ˆλ‹€λ©΄ 0을 λ°˜ν™˜ν•˜κ³ , 그렇지 μ•ŠμœΌλ©΄ 0이 μ•„λ‹Œ 값을 λ°˜ν™˜ν•œλ‹€.

μ°Έκ³ 

λ‹¨μˆœνžˆ μ“°λ ˆλ“œμ˜ 생성 μ‹œ 속성 κ°’μœΌλ‘œ PTHREAD_CREATE_DETACHEDλ₯Ό μ΄μš©ν–ˆλ‹€κ³  ν•΄μ„œ 독립적인 μ“°λ ˆλ“œλ‘œμ¨ μž‘μ—…μ„ 마친 ν›„ μžλ™μœΌλ‘œ μžμ›μ„ λ°˜ν™˜ν•΄μ£ΌλŠ” 것이 μ•„λ‹ˆλ‹€. Detached μ“°λ ˆλ“œλ„ pthread_detachλ₯Ό 톡해 독립적인 μ“°λ ˆλ“œμž„μ„ λͺ…μ‹œν•˜μ—¬, μž‘μ—…μ„ μ™„λ£Œν–ˆμ„ λ•Œ μžλ™μœΌλ‘œ μžμ›μ„ λ°˜ν™˜ν•  수 μžˆλ„λ‘ λ§Œλ“€μ–΄μ•Ό ν•œλ‹€. Detached μ“°λ ˆλ“œμ—κ²Œ μ‚¬μš©ν•˜λŠ” pthread_detachλŠ” νŠΉμ„± 상 μ“°λ ˆλ“œμ˜ μ’…λ£Œλ₯Ό λŒ€κΈ°ν•˜μ§€ μ•ŠλŠ”λ‹€.

4) pthread_cleanup_push

ν•¨μˆ˜ μ›ν˜•

void pthread_cleanup_push(void (*routine)(void *), void *arg);
C

ν•¨μˆ˜ 인자

μ“°λ ˆλ“œμ˜ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” ν•¨μˆ˜κ°€ μ½”λ“œλ₯Ό λκΉŒμ§€ μˆ˜ν–‰ν•˜κΈ° 전에 μ’…λ£Œλœ 경우, 이λ₯Ό μ •λ¦¬ν•˜λŠ” ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  수 μžˆλ„λ‘ Handlerλ₯Ό 등둝할 수 μžˆλ‹€. 이에 ν•΄λ‹Ήν•˜λŠ” 것이 첫 번째 인자이며, Handler의 μΆ”κ°€λŠ” Stack ꡬ쑰둜 μŒ“μ΄κ²Œ λœλ‹€. 그리고 두 번째 μΈμžλŠ” Handler에 μ‚¬μš©λ  인자둜써 μ΄μš©λœλ‹€.
Handler의 싀행이 μ–Έμ œ μ΄λ€„μ§€λŠ”μ§€λŠ” μ°Έκ³  뢀뢄에 κΈ°μž¬λ˜μ–΄ μžˆλ‹€.

λ°˜ν™˜ κ°’

μ•„λ¬΄λŸ° 값도 λ°˜ν™˜ν•˜μ§€ μ•ŠλŠ”λ‹€.

μ°Έκ³ 

HandlerλŠ” Stack ν˜•νƒœλ‘œ μΆ”κ°€λ˜λ©°, pthread_clean_popμ΄λΌλŠ” ν•¨μˆ˜λ₯Ό 톡해 Stackμ—μ„œ μ œκ±°λœλ‹€. μ΄λŠ” μ“°λ ˆλ“œκ°€ pthread_exit으둜 μ’…λ£Œλ˜κ±°λ‚˜ pthread_cancel을 톡해 μ·¨μ†Œλ  경우 μžλ™μœΌλ‘œ ν˜ΈμΆœλœλ‹€. ν˜Ήμ€ pthread_clean_pop의 인자λ₯Ό 0이 μ•„λ‹Œ 값을 λ„£μœΌλ©΄ κ°€μž₯ μ΅œκ·Όμ— μΆ”κ°€ν•œ Handlerλ₯Ό μ œκ±°ν•˜λ©΄μ„œ ν•΄λ‹Ή Handlerλ₯Ό μ‹€ν–‰ν•œλ‹€. 단, pthread_clean_push둜 μΆ”κ°€ν•œ Handler듀은 μ“°λ ˆλ“œμ˜ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” ν•¨μˆ˜κ°€ return으둜 μ’…λ£Œλ˜μ—ˆμ„ λ•ŒλŠ” μ‹€ν–‰λ˜μ§€ μ•ŠλŠ”λ‹€.
Handler의 역할은 pthread_exit 및 pthread_cancel ν•¨μˆ˜μ™€ 관련지어 이해할 수 μžˆλ‹€. μ“°λ ˆλ“œμ˜ μž‘μ—… ν•¨μˆ˜κ°€ λκΉŒμ§€ μˆ˜ν–‰λ˜κΈ° 전에 μ’…λ£Œν•˜κ²Œ 되면, 정리가 ν•„μš”ν•œ μž‘μ—…λ“€μ€ Handlerλ₯Ό 톡해 μ›ν•˜λŠ” μž‘μ—…μ„ μˆ˜ν–‰ν•  수 μžˆλ‹€. λ”°λΌμ„œ μ“°λ ˆλ“œ κ°„ μ˜μ‘΄μ„±μ΄ μžˆλŠ” κ²½μš°μ—λŠ” μ“°λ ˆλ“œμ˜ μ·¨μ†Œ λ“±μœΌλ‘œ μ’…λ£Œλ˜λ”λΌλ„ μ¦‰μ‹œ μžμ›μ„ λ°˜λ‚©ν•˜μ§€ μ•Šκ³  남은 μž‘μ—…μ„ μˆ˜ν–‰ν•  수 μžˆλ„λ‘ ν•˜λŠ” 것이 κ°€λŠ₯ν•˜λ‹€.

5) pthread_cleanup_pop

ν•¨μˆ˜ μ›ν˜•

void pthread_cleanup_pop(int execute);
C

ν•¨μˆ˜ 인자

execute의 값이 0이라면 λ‹¨μˆœνžˆ Stackμ—μ„œ Handlerλ₯Ό μ œκ±°ν•˜κΈ°λ§Œ ν•˜κ³ , execute의 값이 0이 μ•„λ‹ˆλΌλ©΄ μ œκ±°ν•  Handlerλ₯Ό μ‹€ν–‰ν•œ ν›„ μ œκ±°ν•œλ‹€.

λ°˜ν™˜ κ°’

μ•„λ¬΄λŸ° 값도 λ°˜ν™˜ν•˜μ§€ μ•ŠλŠ”λ‹€.

μ°Έκ³ 

pthread_cleanup_pop ν•¨μˆ˜μ˜ μš©λ„λŠ” pthread_cleanup_push둜 μΆ”κ°€λœ Handlerλ₯Ό μ œκ±°ν•  λ•Œ μ΄μš©λœλ‹€. HandlerλŠ” Stack ꡬ쑰둜 μœ μ§€λ˜λ―€λ‘œ pthread_cleanup_pop이 호좜되면 κ°€μž₯ μ΅œκ·Όμ— μΆ”κ°€λœ Handlerκ°€ μ‚­μ œλœλ‹€.

6) pthread_exit

ν•¨μˆ˜ μ›ν˜•

noreturn void pthread_exit(void *retval);
C

ν•¨μˆ˜ 인자

pthread_exit ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œ μ“°λ ˆλ“œλ₯Ό μ¦‰μ‹œ μ’…λ£Œν•˜κ²Œ λ˜λŠ”λ°, 이 λ•Œ retvalμ΄λΌλŠ” ν¬μΈν„°λŠ” λ°˜ν™˜ 값을 μ „λ‹¬ν•˜λŠ”λ° μ΄μš©λœλ‹€.

λ°˜ν™˜ κ°’

noreturn ν‚€μ›Œλ“œμ— 따라 pthread_exit ν•¨μˆ˜λŠ” κ·Έ μ–΄λ–€ 값도 λ°˜ν™˜ν•˜μ§€ μ•ŠλŠ”λ‹€.

μ°Έκ³ 

Detached μ“°λ ˆλ“œλŠ” 독립적인 μ“°λ ˆλ“œλ‘œ μš΄μš©λ˜λ―€λ‘œ retval을 μ΄μš©ν•˜λ”λΌλ„ λ°˜ν™˜ 값을 받을 μ“°λ ˆλ“œκ°€ μ—†λ””. λ”°λΌμ„œ Joinable μ“°λ ˆλ“œμ— λŒ€ν•΄μ„œλ§Œ retval을 μ΄μš©ν•˜μ—¬ pthread_join을 톡해 λ°˜ν™˜ 값을 λ°›μ•„ μ‚¬μš©ν•˜κ²Œ λœλ‹€. λ”°λΌμ„œ retval의 μ΄μš©μ€ μ“°λ ˆλ“œκ°€ μž‘μ—…μ„ μ‹œμž‘ν•œ ν•¨μˆ˜μ—μ„œ return을 톡해 λ°˜ν™˜ν•˜λŠ” ν–‰μœ„ λ™μΌν•˜λ‹€.
λ‹€λ§Œ pthread_exitκ³Ό 일반적인 return에 μ˜ν•œ μ’…λ£Œμ— λŒ€ν•΄μ„œλŠ” 차이가 μžˆλ‹€. μš°μ„  pthread_exit μžμ²΄λŠ” μ“°λ ˆλ“œκ°€ μž‘μ—…μ„ μ‹œμž‘ν•œ ν•¨μˆ˜μ—μ„œ 호좜될 ν•„μš”κ°€ μ—†μŒμ— 따라 μ›ν•˜λŠ” μ§€μ μ—μ„œ μ“°λ ˆλ“œμ˜ μ’…λ£Œλ₯Ό λ§Œλ“€ 수 μžˆλ‹€. 그리고 일반적인 return에 μ˜ν•œ μ’…λ£Œμ—μ„œλŠ” pthread_cleanup_push둜 λ“±λ‘λœ Handlerλ“€μ˜ ν˜ΈμΆœν•˜μ§€ μ•Šμ§€λ§Œ, pthread_exit으둜 μ’…λ£Œλœ κ²½μš°μ—λŠ” Handler듀을 ν˜ΈμΆœν•˜λ©΄μ„œ pthread_cleaup_pop을 μˆ˜ν–‰ν•œλ‹€.

7) pthread_cancel

ν•¨μˆ˜ μ›ν˜•

int pthread_cancel(pthread_t thread);
C

ν•¨μˆ˜ 인자

μž‘μ—…μ„ μ·¨μ†Œν•˜κ³ μž ν•˜λŠ” μ“°λ ˆλ“œμ˜ IDλ₯Ό pthread_t νƒ€μž…μ˜ 인자둜 λͺ…μ‹œν•œλ‹€.

λ°˜ν™˜ κ°’

ν•¨μˆ˜ 호좜이 μ •μƒμ μœΌλ‘œ λ™μž‘ν–ˆλ‹€λ©΄ 0을 λ°˜ν™˜ν•˜κ³ , 그렇지 μ•ŠμœΌλ©΄ 0이 μ•„λ‹Œ 값을 λ°˜ν™˜ν•œλ‹€.

μ°Έκ³ 

μ“°λ ˆλ“œκ°€ μˆ˜ν–‰ν•˜λŠ” μž‘μ—…μ˜ μ·¨μ†ŒλŠ” μ“°λ ˆλ“œμ˜ μ„€μ • 값에 따라 κ°€λŠ₯ μ—¬λΆ€κ°€ κ°ˆλ¦°λ‹€. pthread_setcancelstateλ₯Ό 톡해 PTHREAD_CANCEL_ENABLE 맀크둜둜 μ“°λ ˆλ“œμ˜ μž‘μ—…μ„ μ·¨μ†Œν•  수 μžˆλ„λ‘ μ„€μ •λœ κ²½μš°μ— pthread_cancel ν•¨μˆ˜μ˜ 호좜이 κ°€λŠ₯ν•˜λ‹€.
PTHREAD_CANCEL_ENABLE은 λ³„λ„μ˜ μ„€μ • 없이 μ“°λ ˆλ“œλ₯Ό μƒμ„±ν–ˆλ‹€λ©΄ κΈ°λ³Έ κ°’μœΌλ‘œ μ§€μ •λ˜μ–΄ μžˆλ‹€.
만일 PTHREAD_CANCEL_DISABLE둜 λ˜μ–΄ μžˆλŠ” κ²½μš°μ—λŠ” pthread_cancel의 ν˜ΈμΆœμ„ λ¬΄μ‹œν•˜κ³  λ„˜κΈ°λŠ” 것이 μ•„λ‹ˆλΌ λ³„λ„μ˜ Queue에 λ³΄κ΄€ν•˜μ—¬ PTHREAD_CANCEL_ENABLE이 λ˜μ—ˆμ„ λ•Œ Queue 내에 μœ μ§€λ˜λŠ” μž‘μ—… μ·¨μ†Œλ“€μ„ 순차적으둜 μ²˜λ¦¬ν•œλ‹€.
일단 μ“°λ ˆλ“œ μž‘μ—… μ·¨μ†Œλ₯Ό ν—ˆμš©ν–ˆλ‹€λ©΄, μ·¨μ†Œμ— λŒ€ν•œ μœ ν˜•μ€ 2κ°€μ§€λ‘œ λ‚˜λ‰œλ‹€. PTHREAD_CANCEL_DEFEREED와 PTHREAD_CANCEL_ASYNCHRONOUS μœ ν˜•μ΄ μ‘΄μž¬ν•˜λ©°, pthread_setcanceltypeμ΄λΌλŠ” ν•¨μˆ˜λ₯Ό 톡해 μ„€μ •ν•  수 μžˆλ‹€. 두 값은 μ΄λ¦„μ—μ„œ μ•Œ 수 μžˆλ“―μ΄ μ“°λ ˆλ“œμ˜ μž‘μ—… μ·¨μ†Œλ₯Ό λ―Έλ£¨λŠ” μ‹μœΌλ‘œ 할지 λΉ„λ™κΈ°μ μœΌλ‘œ ν• μ§€λ‘œ λ‚˜λ‰œλ‹€. PTHREAD_CANCEL_DEFERED둜 λ˜μ–΄ μžˆλŠ” κ²½μš°μ—λŠ” μ“°λ ˆλ“œμ˜ μž‘μ—…μ„ μ¦‰μ‹œ μ·¨μ†Œν•˜λŠ” 것이 μ•„λ‹ˆλΌ, Cancellation Point둜 μ •μ˜λœ νŠΉμ • ν•¨μˆ˜κ°€ 호좜될 λ•ŒκΉŒμ§€ μ“°λ ˆλ“œμ˜ μž‘μ—…μ„ μ·¨μ†Œν•˜μ§€ μ•ŠλŠ”λ‹€.
Cancellation Point둜 μ‚¬μš©λ  수 μžˆλŠ” ν•¨μˆ˜λ“€μ€ pthread 맀뉴얼에 검색해보면 κ·Έ λͺ©λ‘μ„ 확인할 수 있으며, λ³„λ„μ˜ 섀정이 μ—†λ‹€λ©΄ PTHREAD_CANCEL_DEFEREDκ°€ κΈ°λ³Έ κ°’μœΌλ‘œ μ§€μ •λ˜μ–΄ μžˆλ‹€.
PTHREAD_CANCEL_ASYNCHRONOUS둜 λ˜μ–΄ μžˆλŠ” κ²½μš°μ—λŠ” λΉ„λ™κΈ°μ μœΌλ‘œ λ™μž‘ν•¨μ— 따라 μ“°λ ˆλ“œ μž‘μ—…μ„ μ¦‰μ‹œ μ·¨μ†Œν•  수 μžˆλ‹€. λ‹€λ§Œ, ν•΄λ‹Ή 값을 μ΄μš©ν•˜λŠ” κ²½μš°μ—λŠ” μ‹œμŠ€ν…œμ— μ˜ν•΄ 보μž₯λ˜μ§€ μ•ŠλŠ” μž‘μ—…μΌ 수 μžˆλ‹€λŠ” 점을 μœ μ˜ν•΄μ•Ό ν•œλ‹€. λ”°λΌμ„œ κΈ°λ³Έ 값인 PTHREAD_CANCEL_DEFEREDλ₯Ό 톡해 μ¦‰μ‹œ μ·¨μ†Œλ₯Ό κ΅¬ν˜„ν•˜μ—¬ μ΄μš©ν•˜λŠ” 것이 μΌλ°˜μ μ΄λ‹€. PTHREAD_CANCEL_DEFEREDλ₯Ό μ΄μš©ν•˜μ—¬ μ¦‰μ‹œ μ·¨μ†Œλ₯Ό μœ λ„ν•  수 μžˆλŠ” 방법은 μ‹œκ·Έλ„μ— λ”°λ₯Έ λ™μž‘μ„ μ‚¬μš©μžκ°€ μ •μ˜ν•˜μ—¬ Cancellation Pointλ₯Ό ν˜ΈμΆœν•˜λ„λ‘ λ§Œλ“€μ–΄ 비동기적인 싀행을 λ§Œλ“œλŠ” 것이닀.
μ“°λ ˆλ“œμ˜ μž‘μ—…μ„ μ·¨μ†Œν•  수 있고 이에 λ”°λ₯Έ 처리 μœ ν˜•μ΄ κ²°μ •λ˜μ—ˆλ‹€λ©΄, μ“°λ ˆλ“œκ°€ μ·¨μ†Œ λ˜μ—ˆμ„ λ•ŒλŠ” pthread_cleanup_push둜 λ“±λ‘λœ Handler듀을 μ‹€ν–‰ν•˜λ©΄μ„œ μ œκ±°ν•˜μ—¬ μ“°λ ˆλ“œκ°€ μ’…λ£Œλœλ‹€.

8) pthread_self

ν•¨μˆ˜ μ›ν˜•

pthread_t pthread_self(void);
C

ν•¨μˆ˜ 인자

인자λ₯Ό 받지 μ•Šκ³  ν•¨μˆ˜λ₯Ό μˆ˜ν–‰ν•œλ‹€.

λ°˜ν™˜ κ°’

ν”„λ‘œμ„ΈμŠ€ λ‚΄μ˜ μ“°λ ˆλ“œλ₯Ό ꡬ뢄할 수 μžˆλŠ” pthread_t νƒ€μž…μ˜ ID 값을 λ°˜ν™˜ν•œλ‹€.

μ°Έκ³ 

pthread_selfλŠ” μ“°λ ˆλ“œ λ‚΄μ—μ„œ ν˜ΈμΆœν•˜λŠ” ν•¨μˆ˜μ΄λ©°, 이 λ•Œ λ°˜ν™˜λ˜λŠ” 값은 pthread_create의 첫 번째 인자인 포인터 κ°’μœΌλ‘œ ν• λ‹Ήλ˜λŠ” μ“°λ ˆλ“œμ˜ ID κ°’κ³Ό λ™μΌν•œ 값이닀.

9) pthread_equal

ν•¨μˆ˜ μ›ν˜•

int pthread_equal(pthread_t t1, pthread_t t2);
C

ν•¨μˆ˜ 인자

λΉ„κ΅ν•˜κ³ μž ν•˜λŠ” 두 μ“°λ ˆλ“œμ˜ ID 값을 인자둜 λ°›λŠ”λ‹€.

λ°˜ν™˜ κ°’

인자둜 λ°›μ•˜λ˜ 두 pthread_tκ°€ μ„œλ‘œ λ‹€λ₯΄λ‹€λ©΄ 0을 λ°˜ν™˜ν•˜κ³ , 그렇지 μ•Šλ‹€λ©΄ 0이 μ•„λ‹Œ 값을 λ°˜ν™˜ν•œλ‹€.

μ°Έκ³ 

pthread_tκ°€ μ •μˆ˜ κ°’μœΌλ‘œ μ •μ˜λœ μ‹œμŠ€ν…œλ„ μžˆκ² μ§€λ§Œ, 그렇지 μ•Šμ€ μ‹œμŠ€ν…œλ„ μžˆλ‹€. μ΄λŠ” pthread_tκ°€ 라이브러리 λ‹¨μœ„μ—μ„œ λͺ…ν™•νžˆ μ •μ˜λœ 것이 μ•„λ‹ˆλΌ μ‹œμŠ€ν…œ λ‹¨μœ„μ˜ μ •μ˜λœ 것을 μ΄μš©ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€. 이 λ•Œ pthread_t에 λŒ€ν•œ μ‹œμŠ€ν…œ λ‹¨μœ„μ˜ μ •μ˜λŠ” 숨겨져 있고 라이브러리 μƒμ—μ„œλŠ” μ„ μ–Έλ§Œ 확인할 수 μžˆλŠ”λ°, 이와 같은 선언을 Forward Declaration이라 ν•˜λ©° pthread_t와 같은 νƒ€μž…μ„ Opaque Type이라 ν•œλ‹€. λ”°λΌμ„œ μ—°μ‚°μžλ₯Ό ν†΅ν•œ pthread_t κ°„μ˜ λͺ…ν™•ν•œ 비ꡐ가 λΆˆκ°€λŠ₯ν•˜κΈ° λ•Œλ¬Έμ— μ“°λ ˆλ“œμ˜ 비ꡐ μ‹œμ—λŠ” pthread_equal ν•¨μˆ˜μ˜ 이용이 λΆˆκ°€ν”Όν•˜λ‹€.
Opaque Type은 λͺ…ν™•ν•œ μ •μ˜λ₯Ό μˆ¨κΉ€μ— 따라 C μ–Έμ–΄λ₯Ό C++κ³Ό 같이 객체 지ν–₯을 μ§€μ›ν•˜λ„λ‘ λ§Œλ“€κ³ μž ν•  λ•Œ μΊ‘μŠν™” (Encapsulation)을 κ΅¬ν˜„ν•˜λŠ”λ° μ΄μš©ν•˜κΈ°λ„ ν•œλ‹€. μ΄λŠ” μ‹œμŠ€ν…œλ§ˆλ‹€ μ •μ˜κ°€ λ‹€λ₯Ό 수 μžˆλ‹€λŠ” 점 λ•Œλ¬Έμ— Implementation Defined와 ν—·κ°ˆλ¦΄ 수 μžˆλŠ”λ°, Implementation DefinedλŠ” μ •μ˜λ₯Ό μˆ¨κΈ°μ§€ μ•Šμ§€λ§Œ Opaque Type은 μ •μ˜λ₯Ό μˆ¨κΈ°λŠ”λ° κ·Έ λͺ©μ μ΄ μžˆμœΌλ―€λ‘œ 차이가 μžˆλ‹€.

10) pthread_kill

ν•¨μˆ˜ μ›ν˜•

int pthread_kill(pthread_t thread, int sig);
C

ν•¨μˆ˜ 인자

λŒ€μƒμ΄ λ˜λŠ” μ“°λ ˆλ“œλ₯Ό pthread_t νƒ€μž…μ˜ ID둜 λͺ…μ‹œν•œλ‹€. 그리고 λ³΄λ‚΄λ €λŠ” μ‹œκ·Έλ„μ„ sig둜 λͺ…μ‹œν•œλ‹€.

λ°˜ν™˜ κ°’

ν•¨μˆ˜ 호좜이 μ •μƒμ μœΌλ‘œ λ™μž‘ν–ˆλ‹€λ©΄ 0을 λ°˜ν™˜ν•˜κ³ , 그렇지 μ•ŠμœΌλ©΄ 0이 μ•„λ‹Œ 값을 λ°˜ν™˜ν•œλ‹€.

μ°Έκ³ 

pthread_kill ν•¨μˆ˜λŠ” 이름 λ•Œλ¬Έμ— pthread_exitκ³Ό μš©λ„λ₯Ό ν—·κ°ˆλ¦΄ 수 μžˆλŠ”λ°, ν•΄λ‹Ή ν•¨μˆ˜λŠ” 일반적인 ν”„λ‘œμ„ΈμŠ€μ—μ„œ kill ν•¨μˆ˜κ°€ μˆ˜ν–‰ν•˜λŠ” 것과 λ™μΌν•œ 역할을 λ§‘λŠ”λ‹€. 비둝 μ‹œκ·Έλ„μ— λŒ€ν•œ λ™μž‘ μˆ˜ν–‰μ„ μ“°λ ˆλ“œ λ‚΄μ—μ„œ μ²˜λ¦¬ν•˜λ”λΌλ„ 정지 ν˜Ήμ€ 재개, μ’…λ£Œμ— λŒ€ν•œ λ™μž‘μ˜ κ²°κ³ΌλŠ” ν”„λ‘œμ„ΈμŠ€ λ‹¨μœ„λ‘œ 이뀄진닀. κ·Έ μ™Έμ˜ λ™μž‘μ€ μ“°λ ˆλ“œ λ‹¨μœ„λ‘œ 이뀄진닀.
만일 pthread_kill의 인자둜 μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” pthread_tλ₯Ό 주게 되면, POSIXμ—μ„œλŠ” Undefined Behavior둜 인식함에 따라 Segmentation Faultλ₯Ό μ•ΌκΈ°ν•  수 μžˆλ‹€. κ·Έ 외에 glibc 같은 ν™˜κ²½μ—μ„œλŠ” pthread_tλ₯Ό λͺ» μ°Ύμ•˜λ‹€λŠ” ESRCHλΌλŠ” 값을 λ°˜ν™˜ν•˜λ„λ‘ λ˜μ–΄ μžˆλ‹€.

3. Mutex

mutex도 μ“°λ ˆλ“œμ™€ 같이 속성에 λŒ€ν•΄ λ‹€μ–‘ν•œ 섀정을 ν•˜λŠ” 것이 κ°€λŠ₯ν•˜λ‹€. mutex의 μœ ν˜• (Type) 이라든가 강건성 (Robustness) λ“±μ˜ 섀정이 κ°€λŠ₯ν•œλ°, μ—¬κΈ°μ„œλŠ” mutex의 μ†μ„±κΉŒμ§€λŠ” 닀루지 μ•ŠλŠ”λ‹€. λ”°λΌμ„œ ν•„μš”ν•˜λ‹€λ©΄ pthread_mutexattr_tλ₯Ό μ°Ύμ•„λ³΄λŠ” 것을 ꢌμž₯ν•œλ‹€. mutex의 μœ ν˜• 및 강건성에 λŒ€ν•΄μ„œλŠ” κ°„λ‹¨ν•˜κ²Œ μ–ΈκΈ‰λœλ‹€.

1) pthread_mutex_init

ν•¨μˆ˜ μ›ν˜•

int pthread_mutex_init(pthread_mutex_t *restrict, const pthread_mutexattr_t *restrict);
C

ν•¨μˆ˜ 인자

μ“°λ ˆλ“œ λ‚΄μ—μ„œ μ‚¬μš©ν•  mutexλ₯Ό ν• λ‹Ή λ°›κΈ° μœ„ν•΄ pthread_mutex_t의 μ£Όμ†Œλ₯Ό λ°›λŠ”λ‹€. λ˜ν•œ mutex의 속성을 κ²°μ • 짓기 μœ„ν•΄ ν•΄λ‹Ή μ„€μ • 값듀이 기둝된 pthread_mutexattr_t의 μ£Όμ†Œλ₯Ό 인자둜 λ°›λŠ”λ‹€.

λ°˜ν™˜ κ°’

ν•¨μˆ˜ 호좜이 μ •μƒμ μœΌλ‘œ λ™μž‘ν–ˆλ‹€λ©΄ 0을 λ°˜ν™˜ν•˜κ³ , 그렇지 μ•ŠμœΌλ©΄ 0이 μ•„λ‹Œ 값을 λ°˜ν™˜ν•œλ‹€.

μ°Έκ³ 

μ„€μ •ν•  속성이 μ—†λ‹€λ©΄ pthread_mutexattr_t의 μ£Όμ†Œμ— λŒ€ν•΄μ„œ NULL을 주어도 λœλ‹€. 이 λ•ŒλŠ” μ‹œμŠ€ν…œ κΈ°λ³Έ μ†μ„±μœΌλ‘œ mutexλ₯Ό μƒμ„±ν•˜κ²Œ λœλ‹€.
μƒμ„±λœ pthread_mutex_t의 이용이 끝났닀면 λ°˜λ“œμ‹œ pthread_mutex_destroyλ₯Ό μ΄μš©ν•˜μ—¬ mutexλ₯Ό ν•΄μ œν•΄μ•Ό ν•œλ‹€. 이미 ν•΄μ œλœ mutex에 λŒ€ν•΄μ„œ pthread_mutex_init의 ν˜ΈμΆœμ€ 문제 μ—†μ§€λ§Œ, 이미 ν• λ‹Ήλœ mutex에 λŒ€ν•΄ pthread_mutex_init을 λ‹€μ‹œ ν˜ΈμΆœν•˜λŠ” ν–‰μœ„λŠ” Undefined Behavior이닀.
pthread_mutex_init을 ν˜ΈμΆœν•˜λŠ” 방법 외에도 PTHREAD_MUTEX_INITIALIZERλ₯Ό pthread_mutex_t의 μ„ μ–Έ μ‹œ ν• λ‹Ήν•˜λŠ” 방법도 μžˆλ‹€. 이λ₯Ό ν†΅ν•œ mutex의 할당은 pthread_mutexattr_tλ₯Ό μ΄μš©ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— mutex의 속성을 κ²°μ • 지을 수 μ—†μœΌλ―€λ‘œ μ‹œμŠ€ν…œ κΈ°λ³Έ μ†μ„±μœΌλ‘œ mutexλ₯Ό μƒμ„±ν•˜κ²Œ λœλ‹€. 비둝 μ •μ μœΌλ‘œ ν• λ‹Ήλœ κ²ƒμ²˜λŸΌ 보이긴 ν•˜λ‚˜ κ·Έ κ²°κ³ΌλŠ” pthread_mutex_init에 속성 값을 NULL둜 넣은 것과 λ™μΌν•˜κ²Œ 동적인 ν• λ‹ΉμœΌλ‘œ 이뀄진닀.
두 ν• λ‹Ή 방법을 비ꡐ해보면, pthread_mutex_init은 λ°˜ν™˜ 값을 톡해 mutex 할당에 λ¬Έμ œκ°€ μžˆμ—ˆλŠ”μ§€ 확인할 수 μžˆλŠ” λ°˜λ©΄μ— PTHREAD_MUTEX_INITIALIZERλŠ” λ³„λ„μ˜ 문제 확인이 λ™λ°˜λ˜μ§€ μ•ŠλŠ”λ‹€. λ”°λΌμ„œ 디버깅 및 개발 λ‹¨κ³„μ—μ„œλŠ” pthread_mutex_init을 톡해 검증을 ν•˜κ³ , 검증이 μš”κ΅¬λ˜μ§€ μ•ŠλŠ” μƒν™©μ—μ„œλŠ” PTHREAD_MUTEX_INITIALIZERλ₯Ό μ“°λŠ” λ“± 상황에 λ§žλŠ” 선택을 ν•˜λ©΄ λœλ‹€.
PTHREAD_MUTEX_INITIALIZERμ—μ„œ λ¬Έμ œκ°€ 생겨 이λ₯Ό μ΄μš©ν•˜κ²Œ λœλ‹€λ©΄, μ΄λŠ” 곧 Undefined Behavior둜 이어진닀.
만일 PTHREAD_MUTEX_INITIALIZERλ₯Ό μ΄μš©ν•  것이라면 μ„ μ–Έ 이후에 ν•΄λ‹Ή 값을 ν• λ‹Ήν•˜λŠ” μ‹μœΌλ‘œλŠ” μ •μƒμ μœΌλ‘œ mutexλ₯Ό 할당받을 수 μ—†λ‹€λŠ” 점에 μœ μ˜ν•΄μ•Ό ν•œλ‹€.
생성할 수 μžˆλŠ” mutex에 λŒ€ν•œ μ œν•œμ€ κ³ λ €λ˜μ—ˆμ§€λ§Œ, μ‚¬μš©ν•˜λ €λŠ” λ©”λͺ¨λ¦¬ 크기 및 각 ν”„λ‘œκ·Έλž¨λ§ˆλ‹€ μš”κ΅¬ν•˜λŠ” mutex의 μˆ˜κ°€ μƒν™©λ§ˆλ‹€ λ‹€λ₯Ό 수 있기 λ•Œλ¬Έμ— λ°˜λ €λ˜μ—ˆλ‹€.

2) pthread_mutex_destroy

ν•¨μˆ˜ μ›ν˜•

int pthread_mutex_destroy(pthread_mutex_t *);
C

ν•¨μˆ˜ 인자

ν•΄μ œν•˜κ³ μž ν•˜λŠ” pthread_mutex_t νƒ€μž…μ˜ mutex에 λŒ€ν•œ μ£Όμ†Œλ₯Ό λ°›λŠ”λ‹€.

λ°˜ν™˜ κ°’

ν•¨μˆ˜ 호좜이 μ •μƒμ μœΌλ‘œ λ™μž‘ν–ˆλ‹€λ©΄ 0을 λ°˜ν™˜ν•˜κ³ , 그렇지 μ•ŠμœΌλ©΄ 0이 μ•„λ‹Œ 값을 λ°˜ν™˜ν•œλ‹€.

μ°Έκ³ 

λ°˜λ“œμ‹œ unlcok된 mutex에 λŒ€ν•΄μ„œλ§Œ pthread_mutex_destroyλ₯Ό ν˜ΈμΆœν•  수 μžˆλ„λ‘ ν•œλ‹€. lock이 λ˜μ–΄ μžˆλŠ” μƒνƒœμ—μ„œ mutexλ₯Ό ν•΄μ œν•˜λŠ” ν–‰μœ„λŠ” Undefined Behavior이닀. λ˜ν•œ pthread_cond_timewait ν˜Ήμ€ pthread_cond_waitκ³Ό 같은 ν•¨μˆ˜μ—μ„œ μ΄μš©ν•˜κ³  μžˆλŠ” mutexλ₯Ό ν•΄μ œν•˜λŠ” ν–‰μœ„ μ—­μ‹œ Undefined Behavior이닀.

3) pthread_mutex_trylock

ν•¨μˆ˜ μ›ν˜•

int pthread_mutex_trylock(pthread_mutex_t *);
C

ν•¨μˆ˜ 인자

μ–»κ³ μž ν•˜λŠ” pthread_mutex_t νƒ€μž…μ˜ mutex에 λŒ€ν•œ μ£Όμ†Œλ₯Ό 인자둜 λ°›λŠ”λ‹€.

λ°˜ν™˜ κ°’

mutexλ₯Ό 얻을 수 μžˆλ‹€λ©΄ mutexλ₯Ό μ·¨λ“ν•œ λ’€ 0을 λ°˜ν™˜ν•˜κ³ , mutexλ₯Ό 얻을 수 μ—†λ‹€λ©΄ Busy Waiting μ΄λ‚˜ Sleep을 λ§Œλ“€μ§€ μ•Šκ³  0이 μ•„λ‹Œ 값을 λ°˜ν™˜ν•œλ‹€.

μ°Έκ³ 

mutex을 μ·¨λ“ν•˜λŠ” κ³Όμ •μ—μ„œ pthread_mutex_trylock을 ν˜ΈμΆœν•˜μ—¬ mutex을 μž‘μ„ 수 μ—†λŠ” 상황일 λ•Œ, 기쑴에 μ·¨λ“ν•œ mutex을 λ²„λ¦¬λŠ” μ‹μœΌλ‘œ Deadlock을 λ°©μ§€ν•˜λ„λ‘ μ²˜λ¦¬λ˜μ–΄ μžˆλ‹€κ³  ν•΄λ³΄μž. 예λ₯Ό λ“€μ–΄, 두 μ“°λ ˆλ“œ AA와 BBκ°€ μžˆλ‹€κ³  ν•΄λ³΄μž. μ“°λ ˆλ“œ AAλŠ” lock1을 μ·¨λ“ν•œ 상황일 λ•Œ, lock2λ₯Ό μž‘μ„ 수 μ—†λ‹€λ©΄ lock1을 λ°˜ν™˜ν•˜λ„λ‘ λ˜μ–΄ μžˆλ‹€. μ“°λ ˆλ“œ BBλŠ” lock2λ₯Ό μ·¨λ“ν•œ 상황일 λ•Œ, lock1을 μž‘μ„ 수 μ—†λ‹€λ©΄ lock2λ₯Ό λ°˜ν™˜ν•˜λ„λ‘ λ˜μ–΄ μžˆλ‹€. 두 μž‘μ—…μ€ Deadlock에 빠질 것 같은 상황이라면 μ„œλ‘œ κ°–κ³  μžˆλŠ” mutex을 λ°˜ν™˜ν•¨μœΌλ‘œμ¨ Deadlock을 λ°©μ§€ν•˜λŠ” 것을 λ³Ό 수 μžˆλŠ”λ°, 두 μ“°λ ˆλ“œκ°€ ν•΄λ‹Ή μž‘μ—…μ„ λ™μ‹œμ— μˆ˜ν–‰ν•  경우 mutexλ₯Ό μ£Όκ³  λ°›λŠ” ν–‰μœ„λ₯Ό λ°˜λ³΅ν•˜κ²Œ 될 수 μžˆλŠ”λ° 이λ₯Ό Livelock이라고 ν•œλ‹€. ν•΄λ‹Ή 상황은 볡도에 두 μ‚¬λžŒμ΄ μ„œλ‘œ λΉ„μΌœ μ£Όλ €λŠ”λ° μ—¬μ „νžˆ μ„œλ‘œ λŒ€μΉ˜ν•˜κ³  μžˆλŠ” 상황과 λ™μΌν•˜λ‹€. λ”°λΌμ„œ pthread_mutex_trylock을 μ‚¬μš©ν•˜λ”λΌλ„ μ œμ‹œλœ 상황에 λŒ€ν•΄ μ£Όμ˜ν•΄μ•Ό ν•˜κ³ , Livelock도 Deadlock을 λ°©μ§€ν•˜λŠ” 방법과 λ™μΌν•˜κ²Œ Partial Orderλ₯Ό μ€€μˆ˜ν•¨μœΌλ‘œμ¨ 방지할 수 μžˆλ‹€.

4) pthread_mutex_lock

ν•¨μˆ˜ μ›ν˜•

int pthread_mutex_lock(pthread_mutex_t *);
C

ν•¨μˆ˜ 인자

μ–»κ³ μž ν•˜λŠ” pthread_mutex_t νƒ€μž…μ˜ mutex에 λŒ€ν•œ μ£Όμ†Œλ₯Ό 인자둜 λ°›λŠ”λ‹€.

λ°˜ν™˜ κ°’

ν•¨μˆ˜ 호좜이 μ •μƒμ μœΌλ‘œ λ™μž‘ν–ˆλ‹€λ©΄ 0을 λ°˜ν™˜ν•˜κ³ , 그렇지 μ•ŠμœΌλ©΄ 0이 μ•„λ‹Œ 값을 λ°˜ν™˜ν•œλ‹€.

μ°Έκ³ 

mutexλ₯Ό 얻을 수 μžˆλ‹€λ©΄ mutexλ₯Ό μ·¨λ“ν•œ λ’€ ν•¨μˆ˜κ°€ μ’…λ£Œλ˜κ³ , mutexλ₯Ό 얻을 수 μ—†λŠ” 상황이라면 pthread_mutex_trylockκ³ΌλŠ” 달리 Sleep μƒνƒœλ‘œ λŒ€κΈ°ν–ˆλ‹€κ°€ mutexλ₯Ό μ–»λŠ”λ‹€. mutexλ₯Ό λ‹Ήμž₯ 얻을 수 μžˆλŠ”μ§€ μ—†λŠ”μ§€ μ—¬λΆ€κ°€ μ€‘μš”ν•˜μ§€ μ•ŠμŒμ—λ„ pthread_mutex_trylockκ³Ό 같이 int 값을 λ°˜ν™˜ν•˜λŠ” μ΄μœ λŠ” μ‚¬μš©ν•˜λ €λŠ” mutex의 속성 값에 따라 pthread_mutex_lock의 문제 상황을 κ°λ³„ν•˜κΈ° μœ„ν•΄μ„œμ΄λ‹€.
mutex의 속성 κ°’ μ€‘μ—μ„œλŠ” mutex의 μœ ν˜•μ΄ ν¬ν•¨λ˜λŠ”λ°, μ΄λŠ” PTHREAD_MUTEX_NORMAL, PTHREAD_MUTEX_ERRORCHECK, PTHREAD_MUTEX_RECURSIVE, PTHREAD_MUTEX_DEFAULT와 같이 4κ°€μ§€λ‘œ λ‚˜λ‰œλ‹€.
μ΄λ¦„μ—μ„œλ„ μ•Œ 수 μžˆλ“―μ΄, μœ ν˜•μ— λŒ€ν•œ λ³„λ„μ˜ 속성 κ°’ 섀정이 μ—†λ‹€λ©΄ PTHREAD_MUTEX_DEFAULTκ°€ κΈ°λ³Έ κ°’μœΌλ‘œ μ΄μš©λœλ‹€.
PTHREAD_MUTEX_NORMAL μœ ν˜•μ΄λΌλ©΄, 이미 μ‚¬μš© 쀑인 mutex에 λŒ€ν•΄ λ‹€μ‹œ pthread_mutex_lock을 ν˜ΈμΆœν–ˆμ„ λ•Œ Deadlock이 λ°œμƒν•œλ‹€.
PTHREAD_MUTEX_ERRORCHECK μœ ν˜•μ΄λΌλ©΄, 이미 μ‚¬μš© 쀑인 mutex에 λŒ€ν•΄ λ‹€μ‹œ pthread_mutex_lock을 ν˜ΈμΆœν–ˆμ„ λ•Œ 상황에 λ§žλŠ” μ μ ˆν•œ 값을 λ°˜ν™˜ν•˜κ²Œ λœλ‹€.
PTHREAD_MUTEX_RECURSIVE μœ ν˜•μ΄λΌλ©΄, 이미 μ‚¬μš© 쀑인 mutex에 λŒ€ν•΄ λ‹€μ‹œ pthread_mutex_lock을 ν˜ΈμΆœν–ˆμ„ λ•Œ λ¬Έμ œκ°€ λ˜μ§€ μ•ŠλŠ”λ‹€.
PTHREAD_MUTEX_DEFAULT μœ ν˜•μ΄λΌλ©΄, 이미 μ‚¬μš© 쀑인 mutex에 λŒ€ν•΄ λ‹€μ‹œ pthread_mutex_lock을 ν˜ΈμΆœν•˜λŠ” ν–‰μœ„λŠ” λ‚˜λ¨Έμ§€ 3개의 μœ ν˜• 쀑 ν•˜λ‚˜μ²˜λŸΌ λ™μž‘ν•˜κ±°λ‚˜ 그렇지 μ•ŠμœΌλ©΄ Undefined Behaviorκ°€ λœλ‹€.

5) pthread_mutex_unlock

ν•¨μˆ˜ μ›ν˜•

int pthread_mutex_unlock(pthread_mutex_t *);
C

ν•¨μˆ˜ 인자

λ°˜ν™˜ν•˜κ³ μž ν•˜λŠ” pthread_mutex_t νƒ€μž…μ˜ mutex에 λŒ€ν•œ μ£Όμ†Œλ₯Ό 인자둜 λ°›λŠ”λ‹€.

λ°˜ν™˜ κ°’

ν•¨μˆ˜ 호좜이 μ •μƒμ μœΌλ‘œ λ™μž‘ν–ˆλ‹€λ©΄ 0을 λ°˜ν™˜ν•˜κ³ , 그렇지 μ•ŠμœΌλ©΄ 0이 μ•„λ‹Œ 값을 λ°˜ν™˜ν•œλ‹€.

μ°Έκ³ 

mutexλ₯Ό κ°–κ³  μžˆλŠ” μ“°λ ˆλ“œ μ™Έμ˜ μ“°λ ˆλ“œκ°€ pthread_mutex_unlock을 ν˜ΈμΆœν•˜λŠ” ν–‰μœ„λŠ” λŒ€μƒμ΄ λ˜λŠ” mutex의 μœ ν˜• 및 강건성과 같은 속성 값에 따라 Undefined Behavior일 수 있고 문제 상황에 λ§žλŠ” 값이 pthread_mutex_unlock의 λ°˜ν™˜ κ°’μœΌλ‘œ λ‚˜νƒ€λ‚  수 μžˆλ‹€. λŒ€μ²΄μ μœΌλ‘œ PTHREAD_MUTEX_STALLED_NP둜 μ„€μ •λœ mutexλŠ” Undefined Behaviorλ₯Ό μ•ΌκΈ°ν•˜κ³ , PTHREAD_MUTEX_ROBUST_NP둜 μ„€μ •λœ mutexλŠ” 문제 상황에 λ§žλŠ” 값을 λ°˜ν™˜ν•¨μ— 따라 PTHREAD_MUTEX_ROBUST_NP둜 강건성이 보μž₯된 mutexλŠ” λ°˜λ“œμ‹œ 문제 상황에 λŒ€ν•œ 확인 절차λ₯Ό κ±°μΉ˜λŠ” 것이 ꢌμž₯λœλ‹€.
μ΄λŠ” pthread_mutex_unlock 외에도 pthread_mutex_trylockκ³Ό pthread_mutex_lock λͺ¨λ‘μ—κ²Œ ν•΄λ‹Ήλ˜λ©°, 강건성에 λŒ€ν•΄μ„œλŠ” λ³„λ„μ˜ 섀정이 μ—†μœΌλ©΄ PTHREAD_MUTEX_STALLED_NP둜 μ„€μ •λœλ‹€.
주어진 pthread_mutex_trylock, pthread_mutex_lock, pthread_mutex_unlock에 λŒ€ν•΄μ„œ PTHREAD_MUTEX_ROBUST_NP의 속성을 가진 강건성이 보μž₯된 mutex에 λŒ€ν•΄μ„  mutexλ₯Ό κ°–κ³  μžˆλŠ” μƒνƒœλ‘œ ν”„λ‘œμ„ΈμŠ€ ν˜Ήμ€ μ“°λ ˆλ“œκ°€ μ’…λ£Œλœ κ²½μš°μ— EOWNERDEADλΌλŠ” 값을 λ°˜ν™˜ν•˜κ²Œ λœλ‹€. 이 λ•Œ mutex λ‚΄λΆ€μ—λŠ” ν˜„μž¬ μ‚¬μš©μž μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ μƒνƒœκ°€ 일관적이이 μ•Šλ‹€κ³  νŒλ‹¨ν•˜μ—¬ 비일관성이 κΈ°λ‘λœλ‹€. λ”°λΌμ„œ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ 볡ꡬ 루틴이 μ‘΄μž¬ν•˜λŠ” κ²½μš°μ—λŠ” pthread_mutex_consistentλΌλŠ” ν•¨μˆ˜λ₯Ό 톡해 mutex의 비일관성을 μΌκ΄€μ„±μœΌλ‘œ μˆ˜μ •ν•˜κ³  pthread_mutex_unlcok으둜 mutexλ₯Ό λ°˜λ‚©ν•œ 뒀에 μ΄μ–΄μ„œ μž‘μ—…μ„ 진행해야 ν•œλ‹€. 만일 μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ 볡ꡬ 루틴이 μ—†κ±°λ‚˜ μž‘λ™λ˜μ§€ μ•ŠλŠ” κ²½μš°μ—λŠ” mutex의 비일관성을 μˆ˜μ •ν•  ν•„μš”κ°€ μ—†μœΌλ―€λ‘œ pthread_mutex_consistent의 호좜이 λΆˆν•„μš”ν•˜κ³ , pthread_mutex_unlcok만 ν˜ΈμΆœν•˜μ—¬ mutexλ₯Ό λ°˜λ‚©ν•˜λ„λ‘ ν•œλ‹€.
mutex의 μœ ν˜•μ΄ PTHREAD_MUTEX_RECURSIVE라면 pthread_mutex_unlock이 mutexλ₯Ό λ°˜λ‚©ν•˜λŠ” κ²°κ³Όλ₯Ό λ§Œλ“€μ§€λŠ” μ•Šκ³ , λ‚΄λΆ€μ μœΌλ‘œ μœ μ§€λ˜λŠ” μž¬κ·€ 횟수 값을 ν•˜λ‚˜ κ°μ†Œμ‹œν‚€λŠ” λ™μž‘λ§Œ μˆ˜ν–‰ν•œλ‹€. PTHREAD_MUTEX_RECURSIVE에 λŒ€ν•΄μ„œλŠ” μž¬κ·€ 횟수 값이 0이 되면 mutexκ°€ λ°˜λ‚©λœλ‹€.

4. Reference