Raku의 condition — 락을 위한 조건 변수 만들기
Raku의 condition — 락을 위한 조건 변수 만들기
단순히 락을 획득·해제하는 것보다 더 복잡한 동기화가 필요할 때가 있어요. 예를 들어 어떤 조건이 충족될 때까지 기다렸다가, 그 조건이 만족되면 다른 스레드를 깨워야 하는 상황이죠. Lock의 condition 메서드는 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을 호출해요.
본문
condition메서드는Lock에서Lock::ConditionVariable객체를 만들어 줘요.- 단순 락 획득·해제보다 복잡한 '조건 충족까지 대기' 동기화에 적합해요.
.wait로 조건 충족을 기다리고,.signal로 다른 스레드를 깨워요.