ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Busy Waiting, Sleep
    카테고리 없음 2021. 6. 11. 16:13

     프로그래밍을 하다 보면 동기화를 하기 위해서 혹은 선행 작업이 끝나기를 기다리기 위해서 wait을 하는 경우가 존재한다. 이 때 사용하는 방식으로 sleep 방식이 있고 busy-waiting을 하는 방식이 있는데 두 방식의 차이점에 대해서 정리해볼려고 한다. 아마 대기해야하는 상황에서 별도의 sleep을 사용해보지 않았다면 대부분은 busy-waiting방식을 사용했을 것이다. 보통 이런 대기 상황에 대한 구현을 하는 경우는 쓰레드를 여러개 활용하는 경우에 다른 쓰레드의 선행작업을 기다리는 경우가 있을 수 있고 혹은 멀티 프로세스 환경에서 다른 프로세스의 선행작업이 끝나지 않은 경우 등이 있다. 
     
      A. Busy Waiting
      Busy-waiting이란 어떤 조건을 만족하지 못할 경우에, 그 조건을 만족할 때 까지 다른 작업을 수행하지 않고 기다리는 경우를 의미한다. 수도 코드로 보면 더 직관적으로 알 수 있다:

        while (cond()) {
        }
        doTask();


      위와 같이 구현할 수 있고, Task를 수행하기 이전에 컨디션을 만족하는지 계속해서 loop을 활용해서 검사하는 로직을 넣는 방식이다. 가장 직관적인 waiting방식이지만 치명적인 단점이 있는데, 프로세스가 계속해서 condition검사를 하고 있기 때문에 그에 대한 조건검사 작업을 수행하고 있는 것이고, 그렇기 때문에 CPU자원을 계속해서 활용하게 된다
      
      B. Sleep
      Sleep을 활용하는 방식은 어떤 조건을 만족시키지 못하면 특정 시간동안 sleep상태로 프로세스를 두고, 이후에 조건을 확인하는 방식이다. 수도코드를 보면 아래와 같다:

        while (cond()) {
          sleep(1);
        }
       doTask();


      사실 Busy-Waiting이랑 구현상에 차이는 거의 없지만 CPU자원 활용을 훨씬 더 효율적으로 할 수 있다. 하지만 쉽게 생각할 수 있겠지만 그만큼 반응을 느리게할 수 밖에 없다. 또한 프로세스가 잠든 상태일 동안 다른 프로세스의 작업을 수행하게 되니까 Context Switching을 하는 비용도 생긴다.
      
      C. Busy-waiting vs Sleep
      Busy-waiting은 위에서 말했듯이 CPU를 많이 소모한다는 문제는 남아있다. 하지만 만약에 기다리고 있는 Task가 자주 호출되고 금방 끝나는 경우에는 잦은 Context Switching이 비쌀 수 있기 때문에 효율적으로 쓰이는 경우도 있으며 대표적으로 Spinlock이 여기에 해당한다. 그리고 busy-waiting의 단점을 줄이기 위해서 sleep을 활용하는데, wait사이에 CPU점유를 내주면서 자원을 효율적으로 활용할 수 있게 해준다. 대신 그만큼 sleep에 대한 오버헤드가 생기는 단점이 있긴 하다.
      
      D. Sleep and Wake up
       Busy-waiting과 Sleep을 비교했는데, 이렇게 봤을 때 Sleep의 방식이 효율적이긴 하지만 포기하는게 너무 많아보인다. 실제 프로그래밍 하는 상황에서 Sleep을 위와 같이 구현하는 경우는 거의 없다. 왜냐하면 시간을 주는 방식도 너무 ad-hoc한 방식이고 한계가 명확하다. 그래서 보통은 sleep and wake up을 사용하는데, 만약에 조건을 만족하지 못하면 프로세스는 sleep상태에 빠지게 한다. 그리고 외부 프로세스 혹은 쓰레드에서 조건문을 만족시키게 될 때 sleep된 프로세스들을 깨워주는 방식이다. 이런 방식이 시스템 프로그램에서는 많이 쓰이고 epoll과 같이 fd의 변화를 감시할 때 사용된다.
       
       E. 요약
       Busy-waiting이란 CPU를 계속해서 사용하며 특정 조건을 만족할 때 까지 대기하는 방식이고, sleep은 CPU점유를 하지 않고 조건을 만족할 때까지 잠들어서 CPU자원 효율성을 늘리는 대기 방식이다. 대부분의 시스템 프로그래밍에서는 sleep and wake up 방식으로 대기하며, 때로는 Context Switching의 부담을 줄여주기 위해서 busy-waiting 방식을 활용하기도 한다.

Designed by Tistory.