Search

<semaphore.h>

Created
2021/07/20
tag
C
Philosophers
semaphore.h
process
semaphore

Subjects

β€’
<semaphore.h>μ—λŠ” semaphoreλ₯Ό λ‹€λ£° 수 μžˆλŠ” ν•¨μˆ˜λ“€μ΄ λ‹€μˆ˜ μ‘΄μž¬ν•œλ‹€. <semaphore.h> λ‚΄μ—μ„œ μ‚¬μš©ν•  수 μžˆλŠ” semaphoreλŠ” Named Semaphore와 Unnamed Semaphore둜 λ‚˜λ‰˜λŠ”λ°, Mac OS Xμ—μ„œλŠ” Unnamed Semaphoreλ₯Ό Deprecated둜 두어 이와 κ΄€λ ¨λœ ν•¨μˆ˜λ“€μ„ ν—ˆμš©ν•˜μ§€ μ•ŠλŠ”λ‹€. λ¬Όλ‘  Linux μƒμ—μ„œλŠ” <semaphore.h>에 μ‘΄μž¬ν•˜λŠ” λͺ¨λ“  ν•¨μˆ˜λ“€μ„ μ΄μš©ν•  수 μžˆμ§€λ§Œ, μ—¬κΈ°μ„œλŠ” Mac OS Xμ—μ„œ μ‚¬μš©ν•  수 μžˆλŠ” ν•¨μˆ˜λ“€λ§Œ λ‹€λ£¬λ‹€λŠ” 것을 사전에 λ°νžŒλ‹€.
λ˜ν•œ λ‹¨μˆœνžˆ semaphoreλ₯Ό μ“Έ 수 있고 없고에 λŒ€ν•œ 곡뢀도 μ’‹μ§€λ§Œ, Async-Signal-Safe, Thread-Safe, Reentratn와 같은 ν‚€μ›Œλ“œλ₯Ό μ ‘ν•¨μœΌλ‘œμ¨ 이듀에 λŒ€ν•œ κ°œλ… 정리λ₯Ό ν•΄λ³΄λŠ” 것도 μ’‹κ² λ‹€λŠ” 생각이 λ“€μ—ˆλ‹€. λ”°λΌμ„œ μ œμ‹œλœ 3가지 ν‚€μ›Œλ“œμ— λŒ€ν•΄μ„œλ„ κΌ­ μ°Ύμ•„λ³΄λŠ” 것을 κΆŒν•œλ‹€.

1. Semaphore

1) sem_open

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

sem_t *sem_open(const char *name, int oflag); sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);
C

ν•¨μˆ˜ 인자

semaphore의 이름을 const char * νƒ€μž…μ˜ name으둜 κ²°μ •ν•  수 μžˆλ‹€.
oflagλŠ” sem_open을 μˆ˜ν–‰ μž‘μ—…μ— λŒ€ν•œ μ„€μ • κ°’μœΌλ‘œ O_CREAT와 O_EXCL을 μ‚¬μš©ν•  수 μžˆλ‹€.
modeλŠ” semaphore에 λŒ€ν•œ κΆŒν•œ μ„€μ • κ°’μœΌλ‘œ 8μ§„μˆ˜ κ°’μœΌλ‘œ κΈ°μž¬ν•˜λ©΄ λ˜λŠ”λ°, <stat.h>λ₯Ό 포함할 μ‹œμ—λŠ” ν•΄λ‹Ή 헀더 내에 μžˆλŠ” 맀크둜 값을 μ΄μš©ν•  μˆ˜λ„ μžˆλ‹€.
valueλŠ” semaphoreκ°€ λ³΄μœ ν•˜κ³  μžˆλŠ” LOCK의 수λ₯Ό μ„€μ •ν•  λ•Œ μ΄μš©λœλ‹€.

λ°˜ν™˜ κ°’

sem_open μž‘μ—…μ„ μ„±κ³΅ν–ˆμ„ λ•ŒλŠ” semaphore에 λŒ€ν•œ μ£Όμ†Œ 값을 λ°˜ν™˜ν•œλ‹€. μ‹€νŒ¨ μ‹œμ—λŠ” SEM_FAILEDλΌλŠ” 맀크둜 값을 λ°˜ν™˜ν•œλ‹€.
sem_tλŠ” intλ₯Ό λ‹¨μˆœνžˆ νƒ€μž… μ •μ˜ν•œ νƒ€μž…μ— λΆˆκ³Όν•˜λ‹€. μ΄λŠ” 일반적으둜 파일 λ””μŠ€ν¬λ¦½ν„° 값을 λ‚˜νƒ€λ‚΄κΈ° λ•Œλ¬Έμ— sem_t *λŠ” 파일 λ””μŠ€ν¬λ¦½ν„° 값을 μ°Έμ‘°ν•˜κ³  μžˆλŠ” 포인터에 λΆˆκ³Όν•˜λ‹€. SEM_FAILEDλŠ” (sem_t *)-1 값이기 λ•Œλ¬Έμ— 포인터 λ³€μˆ˜ 내에 λͺ¨λ“  λΉ„νŠΈκ°€ 1둜 μ±„μ›Œμ§„ 값을 μ˜λ―Έν•œλ‹€.

μ°Έκ³ 

O_CREAT은 semaphore 생성에 λŒ€ν•œ 값이고, O_EXCL은 excludeλ₯Ό μ˜λ―Έν•˜μ—¬ 기쑴에 이미 nameμ΄λΌλŠ” semaphoreκ°€ μœ μ§€λ˜κ³  μžˆλŠ”μ§€ ν™•μΈν•˜λŠ” 값이닀.
ν•¨μˆ˜ μ›ν˜•μ΄ 2κ°œκ°€ μ£Όμ–΄μ‘ŒλŠ”λ°, oflag의 κ°’μœΌλ‘œ O_CREAT이 ν¬ν•¨λ˜λŠ” κ²½μš°μ—λŠ” ν•„μˆ˜μ μœΌλ‘œ μΈμžκ°€ 4개짜리 ν•¨μˆ˜ μ›ν˜•μ„ μ΄μš©ν•΄μ•Ό ν•œλ‹€. μΈμžκ°€ 2개짜리인 ν•¨μˆ˜ μ›ν˜•μ€ O_EXCL을 μ‚¬μš©ν•  λ•Œλ§Œ μ΄μš©ν•œλ‹€.
oflag의 값은 μƒλž΅ν•  수 μ—†κΈ° λ•Œλ¬Έμ— ν•„μˆ˜μ μœΌλ‘œ 값을 μ±„μ›Œμ•Όν•˜λ―€λ‘œ O_EXCL을 μˆ˜ν–‰ν•  것이 μ•„λ‹ˆλΌλ©΄ λ°˜λ“œμ‹œ O_CREATλŠ” 포함될 수 밖에 μ—†λ‹€. λ”°λΌμ„œ 이미 μ‘΄μž¬ν•˜λŠ” semaphore에 λŒ€ν•΄μ„œ sem_open을 μˆ˜ν–‰ν•΄μ•Ό ν•œλ‹€λ©΄, O_CREAT이 포함됨에 따라 semaphoreλ₯Ό 또 μƒμ„±ν•˜κ²Œ λ˜λŠ” 것 μ•„λ‹Œκ°€ λΌλŠ” 의문과 μΈμžκ°€ 4개짜리인 ν•¨μˆ˜λ₯Ό μ΄μš©ν•΄μ•Ό ν•˜λ‹ˆ mode와 value 값을 ν•„μˆ˜μ μœΌλ‘œ κΈ°μž¬ν•¨μ— 따라 κΈ°μ‘΄ 값에 영ν–₯을 λΌμΉ˜λŠ” 것이 μ•„λ‹Œκ°€ ν•˜λŠ” 의문이 생길 수 μžˆλ‹€.
μš°μ„  O_CREAT은 name에 λŒ€ν•œ semaphoreκ°€ μ‘΄μž¬ν•˜μ§€ μ•Šμ„ λ•Œλ§Œ semaphoreλ₯Ό μƒμ„±ν•œλ‹€. 그리고 name에 λŒ€ν•œ semaphoreκ°€ 이미 μ‘΄μž¬ν•  λ•Œ O_CREAT을 톡해 sem_open이 μˆ˜ν–‰λ˜λ©΄, 이 λ•Œ 인자둜 μ‚¬μš©ν•œ mode와 valueλŠ” λ¬΄μ‹œλœλ‹€.
즉, mode와 valueλŠ” κΈ°μ‘΄ 값을 μœ μ§€ν•œλ‹€.
O_EXCL이 ν¬ν•¨λœ κ²½μš°μ— sem_open ν•¨μˆ˜λŠ” nameμ΄λΌλŠ” semaphoreκ°€ 이미 μ‘΄μž¬ν•  κ²½μš°μ— 문제 상황에 λŒ€ν•œ errnoλ₯Ό λ°˜ν™˜ν•˜λ„λ‘ λ™μž‘ν•œλ‹€.
oflag에 λŒ€ν•΄μ„œ <fcntl.h>의 λ‹€λ₯Έ 맀크둜 값듀을 μ‚¬μš©ν•˜λŠ” ν–‰μœ„λŠ” μ½”λ“œμ˜ 이식성을 μ €ν•˜ν•˜λ―€λ‘œ μ‚¬μš©ν•˜μ§€ μ•Šλ„λ‘ ν•œλ‹€. 일뢀 μ‹œμŠ€ν…œμ—μ„œλŠ” 이듀을 Undefined Behavior둜 보기도 ν•˜κ³ , λ¬΄μ‹œν•˜κΈ°λ„ ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.

2) sem_unlink

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

int sem_unlink(const char *name);
C

ν•¨μˆ˜ 인자

semaphoreλ₯Ό μ‚­μ œν•  수 μžˆλ„λ‘ cosnt char * νƒ€μž…μ˜ name 인자λ₯Ό μ‚¬μš©ν•œλ‹€.

λ°˜ν™˜ κ°’

sem_unlink μž‘μ—…μ„ μ„±κ³΅ν–ˆμ„ λ•ŒλŠ” 0을 λ°˜ν™˜ν•œλ‹€. μ‹€νŒ¨ μ‹œμ—λŠ” -1을 λ°˜ν™˜ν•œλ‹€.

μ°Έκ³ 

semaphoreλŠ” open ν›„ closeλ₯Ό ν•œλ‹€κ³  ν•΄μ„œ μ‹œμŠ€ν…œ μƒμ—μ„œ 없어지지 μ•ŠλŠ”λ‹€. λ¬Όλ‘  μ‹œμŠ€ν…œμ„ μž¬λΆ€νŒ…ν•˜κ²Œ 되면 기쑴에 μ΄μš©ν•˜κ³  있던 semaphore듀은 μ‚­μ œλ˜μ§€λ§Œ, κ·Έ μ „κΉŒμ§€λŠ” μ»΄ν“¨νŒ… μžμ›μ„ μ†Œλͺ¨ν•˜κ³  있게 λœλ‹€. λ”°λΌμ„œ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” semaphore에 λŒ€ν•΄μ„œλŠ” λ°˜λ“œμ‹œ sem_unlinkλ₯Ό 톡해 μ‚­μ œν•΄μ€˜μ•Ό ν•œλ‹€.
sem_unlinkλŠ” semaphore의 졜초 sem_open 호좜 직후에 λ°”λ‘œ ν˜ΈμΆœλ˜κΈ°λ„ ν•œλ‹€. 이에 따라 semaphoreκ°€ μƒμ„±λ˜μžλ§ˆμž μ‚­μ œλ˜λŠ” κ²ƒμ²˜λŸΌ λ³΄μ΄μ§€λ§Œ, μ‹€μ œλ‘œλŠ” 그렇지 μ•Šλ‹€. ν”„λ‘œμ„ΈμŠ€ ν˜Ήμ€ μ“°λ ˆλ“œμ— μ˜ν•΄ 참쑰되고 μžˆμ§€ μ•ŠλŠ” semaphoreλŠ” μ¦‰μ‹œ μ‚­μ œλ˜μ§€λ§Œ, 단 ν•˜λ‚˜μ˜ μž‘μ—…μ΄λΌλ„ semaphoreλ₯Ό sem_open ν•˜μ—¬ μ‚¬μš©ν•˜κ³  μžˆλ‹€λ©΄ sem_closeλ₯Ό 톡해 semaphore의 μ°Έμ‘° 값이 0이 되기 μ „κΉŒμ§€λŠ” μ‚­μ œλ˜μ§€ μ•ŠλŠ”λ‹€. λ”°λΌμ„œ sem_unlinkλ₯Ό 미리 ν˜ΈμΆœν•΄λ‘μ–΄λ„ semaphoreλ₯Ό μ¦‰μ‹œ μ‚­μ œν•˜μ§€ μ•ŠλŠ” 것이닀.

3) sem_close

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

int sem_close(sem_t *sem);
C

ν•¨μˆ˜ 인자

λŒ€μƒμ΄ λ˜λŠ” semaphore의 μ£Όμ†Œλ₯Ό 인자둜 λ°›λŠ”λ‹€.

λ°˜ν™˜ κ°’

sem_unlink μž‘μ—…μ„ μ„±κ³΅ν–ˆμ„ λ•ŒλŠ” 0을 λ°˜ν™˜ν•œλ‹€. μ‹€νŒ¨ μ‹œμ—λŠ” -1을 λ°˜ν™˜ν•œλ‹€.

μ°Έκ³ 

close ν•¨μˆ˜μ™€ λ™μΌν•˜κ²Œ, ν”„λ‘œμ„ΈμŠ€κ°€ μ’…λ£Œλ˜λ©΄ sem_open된 semaphore에 λŒ€ν•΄ μžλ™μœΌλ‘œ sem_closeλ₯Ό μˆ˜ν–‰ν•œλ‹€. μ΄λŠ” execve와 같은 exec 계열 ν•¨μˆ˜μ— λŒ€ν•΄μ„œλ„ μžλ™μœΌλ‘œ sem_closeκ°€ μˆ˜ν–‰λœλ‹€.

4) sem_trywait

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

int sem_trywait(sem_t *sem);
C

ν•¨μˆ˜ 인자

LOCK을 μ·¨λ“ν•˜κ³ μž ν•˜λŠ” semaphore의 μ£Όμ†Œλ₯Ό 인자둜 λ°›λŠ”λ‹€.

λ°˜ν™˜ κ°’

sem_trywait μž‘μ—…μ„ μ„±κ³΅ν–ˆμ„ λ•ŒλŠ” 0을 λ°˜ν™˜ν•œλ‹€. μ‹€νŒ¨ μ‹œμ—λŠ” -1을 λ°˜ν™˜ν•œλ‹€.

μ°Έκ³ 

LOCK을 취득할 수 μžˆλ‹€λ©΄ LOCK을 μ·¨λ“ν•œ 뒀에 ν•¨μˆ˜κ°€ μ’…λ£Œλ˜κ³ , 취득할 수 μžˆλŠ” LOCK이 없어도 ν•¨μˆ˜κ°€ μ’…λ£Œλœλ‹€. sem_trywait에 λŒ€ν•΄μ„  취득할 수 μžˆλŠ” LOCK이 μ—†λŠ” 것도 ν•¨μˆ˜ μˆ˜ν–‰ μ‹€νŒ¨λ‘œ κ°„μ£Όλ˜μ–΄ -1이 λ°˜ν™˜λœλ‹€.

5) sem_wait

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

int sem_wait(sem_t *sem);
C

ν•¨μˆ˜ 인자

LOCK을 μ·¨λ“ν•˜κ³ μž ν•˜λŠ” semaphore의 μ£Όμ†Œλ₯Ό 인자둜 λ°›λŠ”λ‹€.

λ°˜ν™˜ κ°’

sem_wait μž‘μ—…μ„ μ„±κ³΅ν–ˆμ„ λ•ŒλŠ” 0을 λ°˜ν™˜ν•œλ‹€. μ‹€νŒ¨ μ‹œμ—λŠ” -1을 λ°˜ν™˜ν•œλ‹€.

μ°Έκ³ 

LOCK을 취득할 수 μžˆλ‹€λ©΄ LOCK을 μ·¨λ“ν•œ 뒀에 ν•¨μˆ˜κ°€ μ’…λ£Œλ˜κ³ , 취득할 수 μžˆλŠ” LOCK이 μ—†μœΌλ©΄ sem_trywaitκ³ΌλŠ” 달리 Sleep μƒνƒœλ‘œ λŒ€κΈ°ν–ˆλ‹€κ°€ LOCK을 μ–»λŠ”λ‹€. LOCK을 λ‹Ήμž₯ 얻을 수 μžˆλŠ”μ§€ μ—†λŠ”μ§€ μ—¬λΆ€κ°€ μ€‘μš”ν•˜μ§€ μ•ŠμŒμ—λ„ sem_trywaitκ³Ό 같이 int 값을 λ°˜ν™˜ν•˜λŠ” μ΄μœ λŠ” 문제 상황을 κ°λ³„ν•˜κΈ° μœ„ν•΄μ„œμ΄λ‹€.

6) sem_post

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

int sem_post(sem_t *sem);
C

ν•¨μˆ˜ 인자

LOCK을 λ°˜λ‚©ν•  수 μžˆλ„λ‘ LOCK을 κ°–κ³  μžˆλŠ” semaphore의 μ£Όμ†Œλ₯Ό 인자둜 λ°›λŠ”λ‹€.

λ°˜ν™˜ κ°’

sem_unlink μž‘μ—…μ„ μ„±κ³΅ν–ˆμ„ λ•ŒλŠ” 0을 λ°˜ν™˜ν•œλ‹€. μ‹€νŒ¨ μ‹œμ—λŠ” -1을 λ°˜ν™˜ν•œλ‹€.

μ°Έκ³ 

sem_post의 ν˜ΈμΆœμ€ semaphore의 ν˜„μž¬ LOCK 수λ₯Ό 증가 (increment)ν•˜λŠ” μž‘μ—…μ„ μœ λ„ν•œλ‹€. 이 λ•Œ 결과적으둜 semaphore의 ν˜„μž¬ LOCK μˆ˜λŠ” 적어도 0보닀 크게 λ˜λŠ”λ°, sem_wait에 μ˜ν•΄ Sleep μƒνƒœλ‘œ μžˆλŠ” λ‹€λ₯Έ ν”„λ‘œμ„ΈμŠ€ ν˜Ήμ€ μ“°λ ˆλ“œλ₯Ό κΉ¨μ›Œμ„œ LOCK을 μž‘μ„ 수 μžˆλ„λ‘ ν•΄μ€€λ‹€.

2. Reference