1. Semaphore
Semaphore๋ 1960๋ ๋ Dijkstra์ ์ํด ์ค๊ณ๋ ์์คํ ์ฝ์ ๋๋ค.
mutex์ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ฉํฐ์ค๋ ๋(๋๋ ๋ฉํฐํ๋ก์ธ์ค) ํ๊ฒฝ์์ critical section์ ๊ณต์ ์์์ ์ ๊ทผ์ ์ด๋ฅผ ์ํด ์ฌ์ฉํฉ๋๋ค.
semaphore์ ๊ธฐ๋ณธ์ ์ธ ํน์ง์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- mutual exclusion(์ํธ ๋ฐฐ์ )์ ์ํ block/wakeup ์๊ณ ๋ฆฌ์ฆ
- ํ๋ก์ธ์ค๊ฐ critical section์ ์ ๊ทผํ์ง ๋ชปํ๋ค๋ฉด, ํ๋ก์ธ์ค๋ block ์ํ๊ฐ ๋จ(block : Semaphore queue์ ํด๋น ํ๋ก์ธ์ค๋ฅผ ๋ฑ๋กํ๊ณ , ํ๋ก์ธ์ค๋ CPU์์ release๋จ)
- ํ๋ก์ธ์ค๊ฐ critical section์ ์ด์ฉํ ํ ๋น ์ ธ๋์ฌ ๋, waiting queue์ ์๋ ํ๋ก์ธ์ค๋ฅผ ๊นจ์
- CPU time์ ์๋ชจ๊ฐ ์์ (wait queue์ block๊ณผ wait์ ๋ํ ๋์์ ์ง์)
- waiting queue๊ฐ ํ์์ ์
2. Counting Semaphore
Counting Semaphore์ critical section์ ์ ๊ทผํ ์ ์๋ ํ๋ก์ธ์ค์ ๊ฐ์๋ฅผ n๊ฐ๋ก ์ ํํฉ๋๋ค.
class Semaphore{
private:
int value; //ํ์ฌ ์ฌ์ฉ๊ฐ๋ฅํ Semaphore์ ์
PCB* queue; //Semaphore๋ฅผ ์ฌ์ฉํ๋ ค๊ณ ํ๋ processes
};
Semaphore::Semaphore(n){
value = n; //critical section์ ์ ๊ทผํ ์ ์๋ ํ๋ก์ธ์ค์ ๊ฐ์ n๊ฐ๋ก ์ ํ
}
Semaphore::wait(){
//originally name: "P" operation
value--;
if(value>0){
block the calling process;
add it to the wait queue of this semaphore;
}
}
Semaphore::signal(){
//originally name: "V" operation
value++;
if(value<=0){
remove the first process from the wait queue;
add it to the scheduling queue;
}
}
- wait() : value>=0 ์ผ ๊ฒฝ์ฐ ๋ฐ๋ก semaphore๋ฅผ ์ป์ ์ ์์ -> critical section ์ ๊ทผ ๊ฐ๋ฅ
- signal() : ๋ฐ์๋ semaphore์ ๋ฐํํ๊ณ value๊ฐ์ ์ฆ๊ฐ์ํด. value<=0์ผ ๊ฒฝ์ฐ, wait queue์ ๊ธฐ๋ค๋ฆฌ๋ ํ๋ก์ธ์ค๊ฐ ์๋ค๋ฉด wait queue์ ๊ฐ์ฅ ์ฒซ ํ๋ก์ธ์ค๋ฅผ ๊นจ์ฐ๊ณ scheduling ํ์ ๋๊ฒจ์ semaphore ์ป์ด์ ์์ ์คํ
3. Binary Semaphore
Binary Semaphore์ n=1์ธ Counting semaphore ์ ๋๋ค.
class Semaphore{
private:
int value;
PCB* queue;
};
Semaphore::Semaphore(1){
value = 1;
}
Semaphore::wait(){
//originally name: "P" operation
if(value==1)
value = 0;
else {
//block the calling process;
//add it to the wait queue of this semaphore;
}
}
Semaphore::signal(){
//originally name: "V" operation-
if(queue is not empty){
//remove the first process from the wait queue;
//add it to the scheduling queue;
}
else
value = 1;
}
- wait()
- value == 1 : ์๋ฌด๋ semaphore๋ฅผ ์ป๊ณ ์์ง ์์ -> ์์ ์ด value-- ํ๊ณ semaphore ๊ฐ์ ์ป์ด ๋ค์ ์์ ์ ์ํ
- value == 0 : ๋ค๋ฅธ ํ๋ก์ธ์ค๊ฐ ์ด๋ฏธ semaphore ์ ์ -> ํด๋น ํ๋ก์ธ์ค block
- signal() : waiting queue๊ฐ ๋น์ด์์ง ์๋ค๋ฉด ํ์ ๊ฐ์ฅ ์ฒซ ๋ฒ์งธ ํ๋ก์ธ์ค๋ฅผ ๋ฐํ
4. Mutex Exclusion by Semaphore
Mutex Exclusion(์ํธ๋ฐฐ์ )๋ binary/counting semaphore๋ฅผ ์ด์ฉํฉ๋๋ค.
binary semaphore๋ mutex์ ๋์ผํ ๋ฐฉ์์ผ๋ก ๋์ํฉ๋๋ค. (lock์ ์ป์ ์ค๋ ๋ ํ๋๋ง ๊ณต์ ์์ ์ ๊ทผ ๊ฐ๋ฅ)
์ค๋ ๋/ํ๋ก์ธ์ค๊ฐ critical section์ ์ ๊ทผํ๋ ค๊ณ ํ ๋ ๋จผ์ S.wait()์ ์ด์ฉํด semaphroe์ ์ป์ด์ผ ํฉ๋๋ค.
๊ณต์ ์์ ์ฌ์ฉ ์ดํ S.signal()์ ์ด์ฉํด semaphore์ ๋ฐํํด ์ฃผ๋ฉด wait queue์์ ๊ธฐ๋ค๋ฆฌ๊ณ ์๋ ๋ค๋ฅธ ์ค๋ ๋/ํ๋ก์ธ์ค๊ฐ semaphore์ ์ป์ ์ ์์ต๋๋ค.
5. Resource Allocation by a Counting Semaphore
n๊ฐ์ ํ๋ก์ธ์ค(์ค๋ ๋)๊ฐ ๋์์ semaphore์ ์ป์ด์ ์์ ์ ์ํํ๋ ๊ฒฝ์ฐ, ์ฆ ๋์์ ์คํํ ์ ์๋ resource๊ฐ ์ฌ๋ฌ๊ฐ ์์ ๊ฒฝ์ฐ ์ฌ์ฉํฉ๋๋ค.
์๋ฅผ๋ค์ด 3๊ฐ์ Printer๋ฅผ ๋์์ ์ฌ์ฉํ๋ ค๊ณ ํ๋ค๋ฉด Semaphore์ ๊ฐ์๋ฅผ 3์ผ๋ก ์ง์ ํ๋ฉด ๋ฉ๋๋ค.
6. Synchronization with a Semaphore
ํ๋ก์ธ์ค๋ค ๊ฐ์ ๋๊ธฐํ๋ฅผ ์ํ ๋ชฉ์ ์ผ๋ก Semaphore๋ฅผ ์ฌ์ฉํ ์๋ ์์ต๋๋ค.
์ฌ๊ธฐ์ ๋๊ธฐํ๋, ํ๋ก์ธ์ค๋ค ๊ฐ์ ์์ ์ ์ํํ ๋ ๋์ผํ๊ฒ ์ด๋ค ํ ๊ตฌ๊ฐ๊น์ง ๋ชจ๋ ํ๋ก์ธ์ค๊ฐ ๋๋ฌํ๋๋ก ๊ธฐ๋ค๋ฆฌ๊ณ , ํ๋ก์ธ์ค๊ฐ ๋ชจ๋ ๋๋ฌํ๋ฉด ๋์์ ์์ ์ ์ํํ์ฌ ํ๋ก๊ทธ๋จ์ ํ๋ฆ์ ๋ง์ถ๊ฒ ํ๋ ๊ฒ์ ๋๋ค.
์ด๋ semaphore์ ์ด๊ธฐ๊ฐ์ 0์ผ๋ก ์ค์ ํด์ค์ผ์จ ๋์ํฉ๋๋ค.
semaphore์ ๊ฐ์ด 0์ด๋ฉด ์ด๊ธฐ์ ์๋ฌด๋ semaphore์ ์ป์ ์ ์์ด signal์ ๋ง๋๊ธฐ ์ ๊น์ง wait queue์์ ๊ธฐ๋ค๋ฆฌ๊ฒ ๋ฉ๋๋ค.
์๋ฅผ ๋ค์ด P1์ด P0๋ณด๋ค wait-point์ ๋ ์ผ์ฐ ๋์ฐฉํ๊ฒ waitํ ๊ฒฝ์ฐ P0๋ wait์์ block๋ ์ํ์ด๋ฏ๋ก P0์์ signal์ด ์ฌ ๋ ๊น์ง ์์ ์ ์ํํด ์ฃผ๋ค๊ฐ signal์ ๋์ฐฉํ๋ฉด P1 ํ๋ก์ธ์ค๋ฅผ ํด์ ์์ผ์ค ์ ์์ต๋๋ค.
๋ฐ๋ผ์ P1์ wait ๋ค์์ ์์ ๋ค์ P0 signal ์ ์ ์์ ๋ค๋ณด๋ค ๋จผ์ ์ํ๋ ์ ์์ต๋๋ค.
8. POSIX SEMAPHORES
semaphore์ ๋ฐ๋์ pthread ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ฐ๊ฒฐ๋์ด์ผ ํฉ๋๋ค.
Semaphore initialization
#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);
- parameters
- sem : semaphore ๊ฐ์ฒด
- pshared
- 0 : ํ์ฌ ํ๋ก์ธ์ค ๋ด์์๋ง ์ฌ์ฉ๋จ
- 0์ด ์๋ : ์ฌ๋ฌ ํ๋ก์ธ์ค๊ฐ ๊ณต์ ๋จ
- value : semaphore์ ์ด๊ธฐ ๊ฐ
Semaphore wait operation
#include <semaphore.h>
int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
- sem_wait()
- ์ค๋ ๋๊ฐ semaphore์ ์ป์ ๋๊น์ง ๊ธฐ๋ค๋ฆผ (suspend)
- semaphore์ ์ป์ผ๋ฉด ๋ด๋ถ์ ์ผ๋ก semaphore count๊ฐ ์๋๊ฐ์
- sem_trywait()
- non-blocking
- ๋ง์ฝ ํ์ฌ semaphore๋ฅผ ์ป์ ์ ์๋ค๋ฉด(sem๊ฐ์ด 0๋ณด๋ค ํฌ๋ฉด) semaphore์ ์ป๊ณ ๋ฐํ
- semaphore์ ์ป์ ์ ์๋ค๋ฉด ์ฆ์๋ฐํ๋์ง๋ง ๋ค์ ์ธ๋งํฌ์ด๋ฅผ ์ป์ผ๋ผ๋ error๋ฅผ ๋ฐํ (EAGAIN)
Semaphore post(signal) operations
#include <sekaphore.h>
int sem_post(sem_t* sem);
int sem_getvalue(sem_t *sem, int* sval);
- POSIX์์ semaphore์ signal operation์ ์ด๋ฆ์ post
- sem_post()
- ์๋์ผ๋ก semaphore์ count๊ฐ์ ์ฆ๊ฐ์ํด
- ์ด ํจ์๋ ์ ๋ block๋์ง ์์. ๋น๋๊ธฐ signal handler์ ์ํด ์์ ํ๊ฒ ์ฌ์ฉ๋จ
- sem_getvalue()
- ํ์ฌ semaphore๊ฐ์ด ์ผ๋ง์ง ์์๋
Semaphore destruction
#include <semaphore.h>
int sem_destroy(sem_t* sem);
- sem์ ์ํด semaphore๊ฐ destroy๋จ
- ํด๋น semaphore๊ฐ ์ฌ์ฉํ๋ resource๋ฅผ ํด์
- waiting์ค์ธ ์ค๋ ๋๊ฐ ์์ด์ผ ํจ
9. Example: Mutual Exclusion using Semaphore
<semaphore.c>
#include <semaphore.h>
int cnt = 0; //๊ณต์ ์์(shared variable)
static sem_t hsem; //semaphore ๊ฐ์ฒด ๋ณ์
int main(int argc, char *argv[]){
pthread_t thread1; //main์์๋ 2๊ฐ์ ์ค๋ ๋(thread1, thread2) ์ ์ธ.
pthread_t thread2;
if(sem_init(&hsem, 0, 1) < 0){ //์ฌ์ฉํ๋ ค๊ณ ํ๋ ์ธ๋งํฌ์ด์ ๋ํด ์ด๊ธฐํ, local ํ๋ก์ธ์ค์์๋ง semaphre์ฌ์ฉ, binary semaphore
fprintf(stderr, "Semaphore Initialization Error\n");
return 1;
}
pthread_create(&thread1, NULL, Thread1, NULL);
pthread_create(&thread2, NULL, Thread2, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
printf("%d\n", cnt);
sem_destroy(&hsem);
return 0;
}
void* Thread1(void *arg){
int i, tmp;
for(i=0; i<1000; i++){
sem_wait(&hsem);
tmp = cnt;
usleep(1000);
cnt = tmp+1;
sem_post(&hsem);
}
printf("Thread1 End\n");
return NULL;
}
void* Thread2(void *arg){
int i, tmp;
for(i=0; i<1000; i++){
sem_wait(&hsem);
tmp = cnt;
usleep(1000);
cnt = tmp+1;
sem_post(&hsem);
}
printf("Thread2 End\n");
return NULL;
}
'๐SUBJECT > ๐์์คํ ํ๋ก๊ทธ๋๋ฐ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์์คํ ํ๋ก๊ทธ๋๋ฐ/Linux] 10. Signal Timer(1) (0) | 2020.05.23 |
---|---|
[์์คํ ํ๋ก๊ทธ๋๋ฐ/Linux] 2. File I/O(1) (0) | 2020.05.06 |
[์์คํ ํ๋ก๊ทธ๋๋ฐ/Linux] 1-3. Linux Shell & Basic Commands (0) | 2020.05.05 |
[์์คํ ํ๋ก๊ทธ๋๋ฐ/Linux] 1. Introduction (2) | 2020.04.24 |
๋๊ธ