NET (C #): Thread-local Storage (thread-local Storage) threadstatic, LocalDataStoreSlot and threadlocal<t>
Directory
- 1. Using the ThreadStatic feature
- 2. Using the named LocalDataStoreSlot type
- 3. Using unnamed LocalDataStoreSlot types
- 4. Using the threadlocal<t> type of. NET 4.0
- 5. Emphasize the default values for different methods and TLS
Note: For brevity, the following will replace "thread local storage (thread-local Storage)" with "TLS" three letters.
1. Using the ThreadStatic feature
The threadstatic feature is the simplest use of TLS, and only supports static fields, so you can simply mark this feature on the field:
STR variables in TLS
[ThreadStatic]
static string str = "hehe";
static void Main ()
{
Another thread will only modify the STR variable in its own TLS
Thread th = new Thread (() = {str = "MGen"; Display (); });
Th. Start ();
Th. Join ();
Display ();
}
static void Display ()
{
Console.WriteLine ("{0} {1}", Thread.CurrentThread.ManagedThreadId, str);
}
Operation Result:
3 MGen
1 hehe
As you can see, the str static fields are stored independently in two threads and are not modified by one another.
Return to Directory 2. Using the named LocalDataStoreSlot type
Obviously the threadstatic feature only supports static fields that are too limited. The LocalDataStoreSlot in the net thread type provides better TLS support. Let's take a look at the named LocalDataStoreSlot type, which can be thread.allocatenameddataslot to allocate a named space and destroy a named space by Thread.freenameddataslot. The acquisition and setting of spatial data is through the GetData method of the thread type and the SetData method.
Look at the code:
static void Main ()
{
Create slots
LocalDataStoreSlot slot = Thread.allocatenameddataslot ("slot");
Set the value in TLS
Thread.setdata (slot, "hehe");
Modifying the TLS thread
Thread th = new Thread (() =
{
Thread.setdata (slot, "MGen");
Display ();
});
Th. Start ();
Th. Join ();
Display ();
Clear Slots
Thread.freenameddataslot ("slot");
}
Display the slot value in TLS
static void Display ()
{
LocalDataStoreSlot Dataslot = Thread.getnameddataslot ("slot");
Console.WriteLine ("{0} {1}", Thread.CurrentThread.ManagedThreadId, Thread.getdata (Dataslot));
}
Output:
3 MGen
1 hehe
Return to Directory 3. Using unnamed LocalDataStoreSlot types
Threads also support unnamed localdatastoreslot, unnamed localdatastoreslot do not need to be cleared manually, and the Thread.AllocateDataSlot method is required for allocation. Note Because unnamed localdatastoreslot do not have a name, Therefore, the Thread.getnameddataslot method cannot be used, only the same localdatastoreslot can be referenced in multiple threads to operate on the TLS space, and the named LocalDataStoreSlot code above is changed to an unnamed localdatast Oreslot Execution:
Static LocalDataStoreSlot variables
static LocalDataStoreSlot slot;
static void Main ()
{
Create slots
Slot = Thread.AllocateDataSlot ();
Set the value in TLS
Thread.setdata (slot, "hehe");
Modifying the TLS thread
Thread th = new Thread (() =
{
Thread.setdata (slot, "MGen");
Display ();
});
Th. Start ();
Th. Join ();
Display ();
}
Display the slot value in TLS
static void Display ()
{
Console.WriteLine ("{0} {1}", Thread.CurrentThread.ManagedThreadId, Thread.getdata (slot));
}
The output is similar to the above.
Return to directory 4. Using the threadlocal<t> type of. NET 4.0
The. NET 4.0 thread has added a lot of things, including the threadlocal<t> type, and his appearance has made it much easier to simplify the TLS operation. Threadlocal<t> types and lazy<t> are surprisingly similar, constructor arguments are func<t> used to create objects (which can also be understood as default values for objects), and then use the Value property to get or set the object.
Threadlocal's operation is somewhat more or less like the unnamed localdatastoreslot above, but Threadlocal feels more concise and better understood.
Code:
static threadlocal<string> local;
static void Main ()
{
Create threadlocal and provide default values
Local = new Threadlocal<string> (() = "hehe");
Modifying the TLS thread
Thread th = new Thread (() =
{
Local. Value = "MGen";
Display ();
});
Th. Start ();
Th. Join ();
Display ();
}
Displaying data values in TLS
static void Display ()
{
Console.WriteLine ("{0} {1}", Thread.CurrentThread.ManagedThreadId, Local. Value);
}
Output:
3 MGen
1 hehe
Return to directory 5. Emphasize the default values for different methods and TLS
The above code is a one-thread setting value, another thread directly modifies the value and outputs it, and does not perceive the default value in TLS, the following is a special emphasis on the default status of different methods.
ThreadStatic does not provide a default value:
[ThreadStatic]
static int i = 123;
static void Main ()
{
Output local thread TLS data value
Console.WriteLine (i);
Output another thread TLS data value
ThreadPool.QueueUserWorkItem (_ = Console.WriteLine (i));
Console waits for thread to end
Console.readkey ();
}
Output:
123
0
Obviously the local thread TLS data is 123, and the default value of the static variable is not initialized in another thread.
LocalDataStoreSlot It is easy to see that there is no default value, because initialization can only construct a space and not give it a value, Thread.setdata obviously only sets the data in TLS, or demonstrates it in code:
Static LocalDataStoreSlot slot = Thread.AllocateDataSlot ();
static void Main ()
{
Thread.setdata (slot, 123);
Output local thread TLS data value
Console.WriteLine (Thread.getdata (slot));
Output another thread TLS data value
ThreadPool.QueueUserWorkItem (_ = = Console.WriteLine (Thread.getdata (slot) = = null));
Console waits for thread to end
Console.readkey ();
}
Output:
123
True
The second line is true, then the data in the other thread is null.
The final point:. NET 4.0 threadlocal will provide default values, remember the words I said above "threadlocal operation more or less like the above unnamed LocalDataStoreSlot"? one might ask why it created threadlocal? There's a big difference. Threadlocal can provide default values for data in TLS. (another threadlocal is a generic class, and LocalDataStoreSlot is not).
Code:
Static threadlocal<int> local = new Threadlocal<int> (() = 123);
static void Main ()
{
Output local thread TLS data value
Console.WriteLine (Local. Value);
Output another thread TLS data value
ThreadPool.QueueUserWorkItem (_ = = Console.WriteLine (local). Value));
Console waits for thread to end
Console.readkey ();
}
Output:
123
123
Transfer-net (C #): Thread local Storage (thread-local Storage) threadstatic, LocalDataStoreSlot and threadlocal<t>