A System.Threading.Barrier 는 여러 스레드( 참가자라고 함)가 단계별 알고리즘에서 동시에 작동할 수 있도록 하는 동기화 기본 형식입니다. 각 참가자는 코드의 장벽 지점에 도달할 때까지 실행됩니다. 장벽은 작업의 한 단계의 끝을 나타냅니다. 참가자가 장벽에 도달하면 모든 참가자가 동일한 장벽에 도달할 때까지 차단됩니다. 모든 참가자가 장벽에 도달하면 필요에 따라 단계 후 작업을 호출할 수 있습니다. 이 사후 단계 작업은 다른 모든 스레드가 여전히 차단되는 동안 단일 스레드에서 작업을 수행하는 데 사용할 수 있습니다. 작업이 실행된 후 참가자는 모두 차단 해제됩니다.
다음 코드 조각은 기본 장벽 패턴을 보여 줍니다.
// Create the Barrier object, and supply a post-phase delegate
// to be invoked at the end of each phase.
Barrier barrier = new Barrier(2, (bar) =>
{
// Examine results from all threads, determine
// whether to continue, create inputs for next phase, etc.
if (someCondition)
success = true;
});
// Define the work that each thread will perform. (Threads do not
// have to all execute the same method.)
void CrunchNumbers(int partitionNum)
{
// Up to System.Int64.MaxValue phases are supported. We assume
// in this code that the problem will be solved before that.
while (success == false)
{
// Begin phase:
// Process data here on each thread, and optionally
// store results, for example:
results[partitionNum] = ProcessData(data[partitionNum]);
// End phase:
// After all threads arrive,post-phase delegate
// is invoked, then threads are unblocked. Overloads
// accept a timeout value and/or CancellationToken.
barrier.SignalAndWait();
}
}
// Perform n tasks to run in parallel. For simplicity
// all threads execute the same method in this example.
static void Main()
{
var app = new BarrierDemo();
Thread t1 = new Thread(() => app.CrunchNumbers(0));
Thread t2 = new Thread(() => app.CrunchNumbers(1));
t1.Start();
t2.Start();
}
' Create the Barrier object, and supply a post-phase delegate
' to be invoked at the end of each phase.
Dim barrier = New Barrier(2, Sub(bar)
' Examine results from all threads, determine
' whether to continue, create inputs for next phase, etc.
If (someCondition) Then
success = True
End If
End Sub)
' Define the work that each thread will perform. (Threads do not
' have to all execute the same method.)
Sub CrunchNumbers(ByVal partitionNum As Integer)
' Up to System.Int64.MaxValue phases are supported. We assume
' in this code that the problem will be solved before that.
While (success = False)
' Begin phase:
' Process data here on each thread, and optionally
' store results, for example:
results(partitionNum) = ProcessData(myData(partitionNum))
' End phase:
' After all threads arrive,post-phase delegate
' is invoked, then threads are unblocked. Overloads
' accept a timeout value and/or CancellationToken.
barrier.SignalAndWait()
End While
End Sub
' Perform n tasks to run in parallel. For simplicity
' all threads execute the same method in this example.
Shared Sub Main()
Dim app = New BarrierDemo()
Dim t1 = New Thread(Sub() app.CrunchNumbers(0))
Dim t2 = New Thread(Sub() app.CrunchNumbers(1))
t1.Start()
t2.Start()
End Sub
전체 예제는 방법: 동시 작업을 Barrier와 동기화하는 방법을 참조하세요.
참가자 추가 및 제거
인스턴스를 Barrier 만들 때 참가자 수를 지정합니다. 언제든지 동적으로 참가자를 추가하거나 제거할 수도 있습니다. 예를 들어 한 참가자가 문제의 일부를 해결하는 경우 결과를 저장하고, 해당 스레드에서 실행을 중지하고, 장벽에 있는 참가자 수를 줄이도록 호출 Barrier.RemoveParticipant 할 수 있습니다. 호출 Barrier.AddParticipant하여 참가자를 추가하는 경우 반환 값은 새 참가자의 작업을 초기화하는 데 유용할 수 있는 현재 단계 번호를 지정합니다.
깨진 장벽
한 참가자가 장벽에 도달하지 못하면 교착 상태가 발생할 수 있습니다. 이러한 교착 상태를 방지하려면 메서드의 Barrier.SignalAndWait 오버로드를 사용하여 제한 시간 및 취소 토큰을 지정합니다. 이러한 오버로드는 모든 참가자가 다음 단계로 계속 진행하기 전에 확인할 수 있는 부울 값을 반환합니다.
사후 단계 예외
사후 단계 위임자가 예외를 던지면, 그 예외는 BarrierPostPhaseException 객체에 감싸져 모든 참가자에게 전달됩니다.
Barrier vss ContinueWhenAll
장벽은 스레드가 루프에서 여러 단계를 수행하는 경우에 특히 유용합니다. 코드에 하나 또는 두 단계의 작업만 필요하다면, 다음을 포함한 모든 종류의 암시적 조인 사용을 고려하여 System.Threading.Tasks.Task 개체를 사용할지 고민해 보세요.
자세한 내용은 연속 작업을 사용하여 작업을 연결하기를 참조하세요.
참고하십시오
.NET