Counting Semaphores

What is a counting semaphore?

counting semaphore는 value를 가지고 있고 wait과 post의 두 operation을 지원합니다.
post는 semaphore를 증가시키고 바로 return해 줍니다. 
wait은 count가 0이라면 wait할 것입니다. 만약 count가 0이 아니라면 count를 1 감소시키고 바로 return해 줍니다.
이것은 과자박스에 있는 과자를 세는 것과 유사합니다. (또는 보물상자에 금화를 세는 것) 과자를 집기 전에 wait을 호출합니다. 만약 과자가 없다면 wait은 return되지 않을 것입니다. 다른 스레드가 post를 호출해 semaphore를 증가시키기 전까지 계속 wait할 것입니다.
즉, post는 증가시킨 후 바로 return되는 반면 wait은 0이라면 wait을 하고, 아니라면 감소시켜 반환합니다.

How do I create a semaphore?

여기서는 unnamed semaphore를 소개합니다. Mac OS X 는 이 세마포어를 지원하지 않습니다.
제일 먼저 초기값이 0 또는 다른 값이어야 하는지를 결정합니다.(예를 들어, array에 남아있는 공간의 수) 
pthread mutex와는 달리 semaphore를 바로 만드는 방법은 없습니다. sem_init을 이용하여 만들게 됩니다.

#include <semaphore.h>

sem_t s;
int main() {
  sem_init(&s, 0, 10); // returns -1 (=FAILED) on OS X
  sem_wait(&s); // Could do this 10 times without blocking
  sem_post(&s); // Announce that we've finished (and one more resource item is available; increment count)
  sem_destroy(&s); // release resources of the semaphore
}



Can I call wait and post from different threads?

물론 가능합니다. mutex와 달리 서로 다른 스레드에서도 증가와 감소가 가능합니다

Can I use a semaphore instead of a mutex?

물론 가능하지만, semaphore의 overhead는 mutex보다 더 큽니다. semaphore를 사용하러면
semaphore의 count가 1이 되도록 초기화
...lock을 sem_wait으로 대체
...unlock을 sem_post로 대체

Mutex는 post하기 전에 항상 wait을 하는 semaphore입니다.


Can I use sem_post inside a signal handler?

가능합니다. sem_post는 signal handler 안에서 바르게 사용될 수 있는 함수 중 하나입니다. 그렇기 때문에 signal handler 안에서 호출하는 것이 불가능했던(printf같이) 함수들을 호출하는 wait thread도 release할 수 있습니다.

#include <stdio.h>
#include <pthread.h>
#include <signal.h>
#include <semaphore.h>
#include <unistd.h>

sem_t s;

void handler(int signal)
{
    sem_post(&s); /* Release the Kraken! */
}

void *singsong(void *param)
{
    sem_wait(&s);
    printf("I had to wait until your signal released me!\n");
}

int main()
{
    int ok = sem_init(&s, 0, 0 /* Initial value of zero*/); 
    if (ok == -1) {
       perror("Could not create unnamed semaphore");
       return 1;
    }
    signal(SIGINT, handler); // Too simple! See note below

    pthread_t tid;
    pthread_create(&tid, NULL, singsong, NULL);
    pthread_exit(NULL); /* Process will exit when there are no more threads */
}


정확한 프로그램은 멀티스레드 프로그램에서 signal을 사용하지 않습니다. (멀티스레드 프로세스에서 signal의 영향은 명확하지 않습니다 - signal man page) 더 올바른 프로그램인 sigaction을 사용합니다.

Posted by 몰랑&봉봉
,