Jegyzet
Az oldalhoz való hozzáférés engedélyezést igényel. Próbálhatod be jelentkezni vagy könyvtárat váltani.
Az oldalhoz való hozzáférés engedélyezést igényel. Megpróbálhatod a könyvtár váltását.
Az A System.Threading.Barrier egy olyan szinkronizálási primitív, amely lehetővé teszi, hogy több szál (más néven résztvevők) egyidejűleg működjenek egy fázisban lévő algoritmuson. Minden résztvevő addig hajtja végre a kódot, amíg el nem éri az akadálypontot a kódban. Az akadály a munka egy fázisának végét jelöli. Amikor egy résztvevő eléri a korlátot, addig blokkol, amíg az összes résztvevő el nem éri ugyanazt az akadályt. Miután az összes résztvevő elérte a korlátot, igény szerint meghívhat egy fázis utáni műveletet. Ez a fázis utáni művelet egyetlen szál műveleteinek végrehajtására használható, míg az összes többi szál továbbra is le van tiltva. A művelet végrehajtása után minden résztvevő feloldásra kerül.
Az alábbi kódrészlet egy alapszintű akadálymintát mutat be.
// 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
Teljes példa megtekintéséhez lásd: Hogyan szinkronizáljuk az egyidejű műveleteket sorompóval.
Résztvevők hozzáadása és eltávolítása
Példány létrehozásakor Barrier adja meg a résztvevők számát. A résztvevőket bármikor dinamikusan is felveheti vagy eltávolíthatja. Ha például egy résztvevő megoldja a probléma egy részét, tárolhatja az eredményt, leállíthatja a végrehajtást ezen a szálon, és meghívhatja Barrier.RemoveParticipant a sorompóban lévő résztvevők számának csökkentésére. Amikor meghív egy résztvevőt Barrier.AddParticipant, a visszatérési érték megadja az aktuális fázisszámot, amely az új résztvevő munkájának inicializálásához lehet hasznos.
Megtört akadályok
Holtpont akkor fordulhat elő, ha egy résztvevő nem éri el az akadályt. A holtpontok elkerülése érdekében használja a Barrier.SignalAndWait metódus túlterheléseit, hogy megadjon egy időtúllépési időszakot és egy törlési tokent. Ezek a túlterhelések olyan logikai értéket adnak vissza, amelyet minden résztvevő ellenőrizhet, mielőtt továbblép a következő fázisra.
Fázis utáni kivételek
Ha a fázis utáni delegált kivételt ad ki, a rendszer egy BarrierPostPhaseException objektumba csomagolja, amelyet aztán propagál az összes résztvevőnek.
Akadály és ContinueWhenAll
A korlátok különösen akkor hasznosak, ha a szálak több fázist végeznek ciklusokban. Ha a kód csak egy vagy két munkafázist igényel, fontolja meg, hogy használjon-e System.Threading.Tasks.Task objektumokat bármilyen implicit illesztéssel, beleértve a következőket:
További információért lásd: Feladatok láncolása folytatólagos tevékenységek használatával.