illékony (C# referencia)
A volatile
kulcsszó azt jelzi, hogy egy mezőt több szál is módosíthat, amelyek egyszerre hajtanak végre. A fordító, a futtatókörnyezeti rendszer és még a hardver is átrendezheti az olvasást és az írást a memóriahelyekre teljesítménybeli okokból. A deklarált volatile
mezők bizonyos típusú optimalizálásokból ki vannak zárva. Nincs garancia arra, hogy egyetlen teljes sorrendbe rendezze az illékony írásokat az összes végrehajtási szálból látható módon. További információt az osztályban Volatile talál.
Feljegyzés
A többprocesszoros rendszereken az illékony olvasási művelet nem garantálja, hogy a legújabb értéket az adott memóriahelyre bármely processzor írja. Hasonlóképpen, az illékony írási művelet nem garantálja, hogy az írott érték azonnal látható lesz más processzorok számára.
A volatile
kulcsszó az alábbi típusú mezőkre alkalmazható:
- Referenciatípusok.
- Mutatótípusok (nem biztonságos környezetben). Vegye figyelembe, hogy bár maga a mutató volatilis lehet, az objektum, amelyre mutat, nem. Más szóval nem deklarálhat "mutatót volatilisre".
- Olyan egyszerű típusok, mint
sbyte
a ,byte
,short
,ushort
,int
,uint
char
,float
, ésbool
. - Az
enum
alábbi alaptípusok egyikével rendelkező típus:byte
, ,sbyte
,short
,ushort
int
vagyuint
. - Általános típusparaméterek, amelyek ismerten referenciatípusok.
- IntPtr és UIntPtr.
Más típusok , beleértve double
és long
, nem jelölhetők meg volatile
, mert az ilyen típusú mezők olvasása és írása nem garantálható atominak. Az ilyen típusú mezőkhöz való többszálas hozzáférés védelméhez használja az Interlocked osztálytagokat, vagy védje a hozzáférést az lock
utasítással.
A volatile
kulcsszó csak egy vagy struct
több mezőre class
alkalmazható. A helyi változók nem deklarálhatók volatile
.
Példa
Az alábbi példa bemutatja, hogyan deklarálhat nyilvános mezőváltozót volatile
.
class VolatileTest
{
public volatile int sharedStorage;
public void Test(int i)
{
sharedStorage = i;
}
}
Az alábbi példa bemutatja, hogyan hozható létre és használható segéd- vagy feldolgozószál az elsődleges szál feldolgozásával párhuzamosan. A többszálas kezelésről további információt a Felügyelt szálkezelés című témakörben talál.
public class Worker
{
// This method is called when the thread is started.
public void DoWork()
{
bool work = false;
while (!_shouldStop)
{
work = !work; // simulate some work
}
Console.WriteLine("Worker thread: terminating gracefully.");
}
public void RequestStop()
{
_shouldStop = true;
}
// Keyword volatile is used as a hint to the compiler that this data
// member is accessed by multiple threads.
private volatile bool _shouldStop;
}
public class WorkerThreadExample
{
public static void Main()
{
// Create the worker thread object. This does not start the thread.
Worker workerObject = new Worker();
Thread workerThread = new Thread(workerObject.DoWork);
// Start the worker thread.
workerThread.Start();
Console.WriteLine("Main thread: starting worker thread...");
// Loop until the worker thread activates.
while (!workerThread.IsAlive)
;
// Put the main thread to sleep for 500 milliseconds to
// allow the worker thread to do some work.
Thread.Sleep(500);
// Request that the worker thread stop itself.
workerObject.RequestStop();
// Use the Thread.Join method to block the current thread
// until the object's thread terminates.
workerThread.Join();
Console.WriteLine("Main thread: worker thread has terminated.");
}
// Sample output:
// Main thread: starting worker thread...
// Worker thread: terminating gracefully.
// Main thread: worker thread has terminated.
}
Ha a volatile
módosítót hozzáadja a megfelelő deklarációhoz _shouldStop
, mindig ugyanazokat az eredményeket kapja (hasonlóan az előző kódban látható kivonathoz). A tag módosító _shouldStop
nélkül azonban a viselkedés kiszámíthatatlan. A DoWork
módszer optimalizálhatja a taghozzáférést, ami elavult adatok olvasását eredményezi. A többszálas programozás természetéből adódóan az elavult olvasások száma kiszámíthatatlan. A program különböző futtatásai némileg eltérő eredményeket eredményeznek.
C# nyelvspecifikáció
További információkért lásd a C# nyelvi specifikációját. A nyelvi specifikáció a C#-szintaxis és -használat végleges forrása.