Raku의 condition — 락을 위한 조건 변수 만들기

Raku의 condition — 락을 위한 조건 변수 만들기

단순히 락을 획득·해제하는 것보다 더 복잡한 동기화가 필요할 때가 있어요. 예를 들어 어떤 조건이 충족될 때까지 기다렸다가, 그 조건이 만족되면 다른 스레드를 깨워야 하는 상황이죠. Lockcondition 메서드는 Lock::ConditionVariable 객체를 돌려줘요.

method condition(Lock:D: )

조건 변수(condition variable)가 무엇이고 락·뮤텍스와 어떻게 연결되는지 배경이 궁금하다면, 관련 문서나 위키백과를 참고하면 좋아요. 기본 사용은 이렇게 해요.

my $l = Lock.new;
$l.condition;

단순히 락을 얻고 푸는 것을 넘어서는, 좀 더 복잡한 상호작용이 필요할 때 락보다 조건 변수를 쓰는 게 좋아요.

전형적인 예시로, 여러 스레드가 작업을 처리하고 그 결과를 조건 변수로 모아 확인하는 코드를 볼게요.

constant ITEMS = 100;
my $lock = Lock.new;
my $cond = $lock.condition;
my $todo = 0;
my $done = 0;
my @in = 1..ITEMS;
my @out = 0 xx ITEMS;

loop ( my $i = 0; $i < @in; $i++ ) {
    my $in := @in[$i];
    my $out := @out[$i];
    Thread.start( {
      my $partial = $in² +1;
      if $partial.is-prime {
          $out = $partial but "Prime";
      } else {
          $out = $partial;
      }
      $lock.protect( {
         $done++;
         $cond.signal if $done == $todo;
      } );
    } );
    $todo++;
}
$lock.protect( {
    $cond.wait({  $done == $todo } );
});

say @out.map: { $_.^roles > 2 ?? $_.Num ~ "*" !! $_ };
# OUTPUT: «2* 5* 10 17* 26 37* 50 65 82 101* … »

이 예시에서는 조건 변수 $cond로 "모든 숫자가 생성·검사될 때까지" 기다리고, 특정 스레드가 끝났을 때 다른 스레드를 깨우도록 .signal을 호출해요.

출처: Raku 공식 문서 — condition

본문

  • condition 메서드는 Lock에서 Lock::ConditionVariable 객체를 만들어 줘요.
  • 단순 락 획득·해제보다 복잡한 '조건 충족까지 대기' 동기화에 적합해요.
  • .wait로 조건 충족을 기다리고, .signal로 다른 스레드를 깨워요.