Interlocked Osztály
Definíció
Fontos
Egyes információk olyan, kiadás előtti termékekre vonatkoznak, amelyek a kiadásig még jelentősen módosulhatnak. A Microsoft nem vállal kifejezett vagy törvényi garanciát az itt megjelenő információért.
Atomi műveleteket biztosít több szál által megosztott változókhoz.
public ref class Interlocked abstract sealed
public ref class Interlocked sealed
public static class Interlocked
public sealed class Interlocked
type Interlocked = class
Public Class Interlocked
Public NotInheritable Class Interlocked
- Öröklődés
-
Interlocked
Példák
Az alábbi példakód egy szálbiztos erőforrás-zárolási mechanizmust mutat be.
using System;
using System.Threading;
namespace InterlockedExchange_Example
{
class MyInterlockedExchangeExampleClass
{
//0 for false, 1 for true.
private static int usingResource = 0;
private const int numThreadIterations = 5;
private const int numThreads = 10;
static void Main()
{
Thread myThread;
Random rnd = new Random();
for(int i = 0; i < numThreads; i++)
{
myThread = new Thread(new ThreadStart(MyThreadProc));
myThread.Name = String.Format("Thread{0}", i + 1);
//Wait a random amount of time before starting next thread.
Thread.Sleep(rnd.Next(0, 1000));
myThread.Start();
}
}
private static void MyThreadProc()
{
for(int i = 0; i < numThreadIterations; i++)
{
UseResource();
//Wait 1 second before next attempt.
Thread.Sleep(1000);
}
}
//A simple method that denies reentrancy.
static bool UseResource()
{
//0 indicates that the method is not in use.
if(0 == Interlocked.Exchange(ref usingResource, 1))
{
Console.WriteLine("{0} acquired the lock", Thread.CurrentThread.Name);
//Code to access a resource that is not thread safe would go here.
//Simulate some work
Thread.Sleep(500);
Console.WriteLine("{0} exiting lock", Thread.CurrentThread.Name);
//Release the lock
Interlocked.Exchange(ref usingResource, 0);
return true;
}
else
{
Console.WriteLine(" {0} was denied the lock", Thread.CurrentThread.Name);
return false;
}
}
}
}
Imports System.Threading
Namespace InterlockedExchange_Example
Class MyInterlockedExchangeExampleClass
'0 for false, 1 for true.
Private Shared usingResource As Integer = 0
Private Const numThreadIterations As Integer = 5
Private Const numThreads As Integer = 10
<MTAThread> _
Shared Sub Main()
Dim myThread As Thread
Dim rnd As New Random()
Dim i As Integer
For i = 0 To numThreads - 1
myThread = New Thread(AddressOf MyThreadProc)
myThread.Name = String.Format("Thread{0}", i + 1)
'Wait a random amount of time before starting next thread.
Thread.Sleep(rnd.Next(0, 1000))
myThread.Start()
Next i
End Sub
Private Shared Sub MyThreadProc()
Dim i As Integer
For i = 0 To numThreadIterations - 1
UseResource()
'Wait 1 second before next attempt.
Thread.Sleep(1000)
Next i
End Sub
'A simple method that denies reentrancy.
Shared Function UseResource() As Boolean
'0 indicates that the method is not in use.
If 0 = Interlocked.Exchange(usingResource, 1) Then
Console.WriteLine("{0} acquired the lock", Thread.CurrentThread.Name)
'Code to access a resource that is not thread safe would go here.
'Simulate some work
Thread.Sleep(500)
Console.WriteLine("{0} exiting lock", Thread.CurrentThread.Name)
'Release the lock
Interlocked.Exchange(usingResource, 0)
Return True
Else
Console.WriteLine(" {0} was denied the lock", Thread.CurrentThread.Name)
Return False
End If
End Function
End Class
End Namespace
Megjegyzések
Az osztály módszerei segítenek védelmet nyújtani azokkal a hibákkal szemben, amelyek akkor fordulhatnak elő, amikor az ütemező környezeteket vált, miközben egy szál olyan változót frissít, amelyet más szálak érhetnek el, vagy ha két szál egyidejűleg fut külön processzorokon. Az osztály tagjai nem adnak kivételeket.
A Increment változók és Decrement metódusok növekménye vagy csökkentése, valamint az eredményként kapott érték tárolása egyetlen műveletben. A legtöbb számítógépen a változók növekménye nem atomi művelet, amely a következő lépéseket igényli:
- Egy példányváltozóból származó érték betöltése egy regiszterbe.
- Az érték növelése vagy csökkentése.
- Tárolja az értéket a példányváltozóban.
Ha nem használja Increment , és Decrementaz első két lépés végrehajtása után egy szál elővehető. Ezután egy másik szál mindhárom lépést végrehajthatja. Amikor az első szál folytatja a végrehajtást, felülírja a példányváltozó értékét, és a második szál által végrehajtott növekmény vagy csökkenés hatása elveszik.
A Add metódus atomilag hozzáad egy egész számot egy egész szám változóhoz, és visszaadja a változó új értékét.
A Exchange metódus atomilag kicseréli a megadott változók értékeit. A CompareExchange módszer két műveletet kombinál: két érték összehasonlítását és egy harmadik érték tárolását az egyik változóban az összehasonlítás eredménye alapján. Az összehasonlítási és csereműveleteket atomi műveletként hajtjuk végre.
Győződjön meg arról, hogy a megosztott változók írási vagy olvasási hozzáférése atomi. Ellenkező esetben előfordulhat, hogy az adatok sérültek, vagy a betöltött érték helytelen.
Metódusok
| Name | Description |
|---|---|
| Add(Int32, Int32) |
Két 32 bites egész számot ad hozzá, és az első egész számot az összegre cseréli atomi műveletként. |
| Add(Int64, Int64) |
Két 64 bites egész számot ad hozzá, és az első egész számot az összegre cseréli atomi műveletként. |
| CompareExchange(Double, Double, Double) |
Az egyenlőség két dupla pontosságú lebegőpontos számát hasonlítja össze, és ha egyenlőek, az első értéket atomi műveletként cseréli le. |
| CompareExchange(Int32, Int32, Int32) |
Összehasonlít két 32 bites aláírt egész számot az egyenlőséghez, és ha egyenlőek, az első értéket atomi műveletként cseréli le. |
| CompareExchange(Int64, Int64, Int64) |
Összehasonlít két 64 bites aláírt egész számot az egyenlőséghez, és ha egyenlőek, az első értéket atomi műveletként cseréli le. |
| CompareExchange(IntPtr, IntPtr, IntPtr) |
Összehasonlít két natív méretű aláírt egész számot az egyenlőség érdekében, és ha egyenlőek, az elsőt atomi műveletként helyettesíti. |
| CompareExchange(Object, Object, Object) |
Összehasonlít két objektumot a referenciaegyenlőség szempontjából, és ha egyenlőek, az első objektumot atomi műveletként helyettesíti. |
| CompareExchange(Single, Single, Single) |
Az egyenlőség két egypontos lebegőpontos számát hasonlítja össze, és ha egyenlőek, az első értéket atomi műveletként cseréli le. |
| CompareExchange<T>(T, T, T) |
Összehasonlítja a hivatkozási egyenlőség megadott típusának |
| Decrement(Int32) |
Egy megadott változót dekreál, és az eredményt atomi műveletként tárolja. |
| Decrement(Int64) |
A megadott változót dekreálja, és az eredményt atomi műveletként tárolja. |
| Exchange(Double, Double) |
Dupla pontosságú lebegőpontos számot állít be egy megadott értékre, és az eredeti értéket adja vissza atomi műveletként. |
| Exchange(Int32, Int32) |
32 bites aláírt egész számot állít be egy megadott értékre, és az eredeti értéket adja vissza atomi műveletként. |
| Exchange(Int64, Int64) |
Egy 64 bites aláírt egész számot állít be egy megadott értékre, és az eredeti értéket adja vissza atomi műveletként. |
| Exchange(IntPtr, IntPtr) |
Natív méretű aláírt egész számot állít be egy megadott értékre, és az eredeti értéket adja vissza atomi műveletként. |
| Exchange(Object, Object) |
Egy objektumot egy megadott értékre állít be, és az eredeti objektumra mutató hivatkozást ad vissza atomi műveletként. |
| Exchange(Single, Single) |
Egy egypontos lebegőpontos számot állít be egy megadott értékre, és az eredeti értéket adja vissza atomi műveletként. |
| Exchange<T>(T, T) |
A megadott típusú |
| Increment(Int32) |
Egy megadott változót növekményesen tárol, és atomi műveletként tárolja az eredményt. |
| Increment(Int64) |
Egy megadott változót növekményesen tárol, és atomi műveletként tárolja az eredményt. |
| MemoryBarrier() |
A következő módon szinkronizálja a memóriahozzáférést: Az aktuális szálat végrehajtó processzor nem tudja úgy átrendezni az utasításokat, hogy a memória a hívás előtt hozzáférhessen MemoryBarrier() a híváshoz, miután a hívást követő memóriahozzáférések következnek MemoryBarrier(). |
| MemoryBarrierProcessWide() |
Egy folyamatszintű memóriakorlátot biztosít, amely biztosítja, hogy az olvasási és írási műveletek nem haladhatók át az akadályon. |
| Read(Int64) |
Egy 64 bites értéket ad vissza, amely atomi műveletként van betöltve. |
| SpeculationBarrier() |
Definiál egy memóriakerítést, amely blokkolja a spekulatív végrehajtást ezen a ponton, amíg a függőben lévő olvasások és írások befejeződnek. |
A következőre érvényes:
Szálbiztonság
Ez a típus szálbiztos.