장벽
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.RemoveParticipant를 호출하여 장벽의 참가자 수를 줄일 수 있습니다. Barrier.AddParticipant를 호출하여 참가자를 추가하는 경우 반환 값은 새 참가자의 작업을 초기화하는 데 유용할 수 있는 현재 단계 번호를 지정합니다.
한 참가자가 장벽에 도달하지 못할 경우 교착 상태가 발생할 수 있습니다. 이러한 교착 상태를 방지하려면 Barrier.SignalAndWait 메서드의 오버로드를 사용하여 시간 제한 기간 및 취소 토큰을 지정합니다. 이러한 오버로드는 다음 단계로 넘어가기 전에 각 참가자가 확인할 수 있는 부울 값을 반환합니다.
사후 단계 대리자에서 예외가 발생하는 경우 BarrierPostPhaseException 개체에 래핑된 다음 모든 참가자에게 전파됩니다.
장벽은 스레드가 루프로 여러 단계를 수행할 때 특히 유용합니다. 코드에 한두 개의 작업 단계만 필요한 경우 다음을 포함하여 임의 종류의 암시적 조인과 함께 System.Threading.Tasks.Task 개체를 사용할지 여부를 고려합니다.
자세한 내용은 연속 작업을 사용하여 작업 연결을 참조하세요.
.NET 피드백
.NET은(는) 오픈 소스 프로젝트입니다. 다음 링크를 선택하여 피드백을 제공해 주세요.