Mathematical path -vb.net parallel computing (3), -vb.net parallel computing
Next, we can use the following statement to create a local thread variable and use the static TLS function.
Dim betterCounter As ThreadLocal (Of Integer) = New ThreadLocal (Of Integer) (Function () 1)
The value of betterCounter is initialized to 1. In this program, the jg is initialized to 50 and defined as a local variable of the thread.
Dim jg As ThreadLocal (Of Integer) = New ThreadLocal (Of Integer) (Function () 50)
Then, we use jg. Value to read and write the Value of this local variable.
Jg. Value-= mynum
3. Dynamic TLS
Imports System
Imports System. Threading
Module Module1
Sub Main ()
Dim mythread1 As Thread
Dim mythread2 As Thread
Dim mythread3 As Thread
'Create a thread object
Mythread1 = New Thread (AddressOf mythreadrun)
Mythread2 = New Thread (AddressOf mythreadrun)
Mythread3 = New Thread (AddressOf mythreadrun)
Console. WriteLine (Now. ToLongTimeString & "after the thread object is created, start the execution thread ")
'Execution thread
Mythread1.Start ("thread 1 ")
Mythread2.Start ("thread 2 ")
Mythread3.Start ("thread 3 ")
'Wait for the thread to finish
Mythread1.Join ()
Mythread2.Join ()
Mythread3.Join ()
'Thread execution completed
Console. WriteLine (Now. ToLongTimeString & "finished thread execution! ")
End Sub
Public Sub mythreadrun (ByVal data As Object)
Dim mynum As Integer
'Allocate a new slot, which stores local thread data and slot name
'Must be unique
Thread. AllocateNamedDataSlot (data)
Dim jg As LocalDataStoreSlot
Jg = Thread. GetNamedDataSlot (data)
Thread. SetData (jg, 100)
Try
For mynum = 1 To 10
Thread. SetData (jg, Thread. GetData (jg)-mynum)
Console. writeLine (data & "& Now. toLongTimeString & "=>" & (Thread. getData (jg) + mynum) & "-" & mynum & ", the calculation result is:" & Thread. getData (jg ))
Thread. Sleep (2)
Next
Catch
Console. WriteLine (data & "& Now. ToLongTimeString &" thread terminated abnormally! ")
'Terminate the thread
Thread. CurrentThread. Abort ()
Finally
Thread. FreeNamedDataSlot (data)
End Try
End Sub
End Module
The running result is as expected. The jg variable implements the thread local variable through the slot mechanism provided by dynamic TLS.
'Allocate a new slot that stores local thread data. The slot name is
'Myjg, name must be unique
Thread. AllocateNamedDataSlot (data)
Dim jg As LocalDataStoreSlot
Jg = Thread. GetNamedDataSlot (data)
Thread. SetData (jg, 100)
The above code is Guan Jian. We use the named data slot. Of course, we can also use the unnamed data slot, because the unnamed data slot is relatively simple, so the named data slot is used here, we will demonstrate its functions to you.
Note:
If you use the AllocateNamedDataSlot method to allocate a slot with a specified name, this method causes an exception and cannot test whether a slot has been allocated. In addition, the data slots allocated using this method must be released using FreeNamedDataSlot.
All content of this blog is original, if reproduced please indicate the source http://blog.csdn.net/myhaspl/
In this example, we use the following statement to allocate a slot
Thread. AllocateNamedDataSlot (data)
Obtains the reference of a naming slot for further operations.
Jg = Thread. GetNamedDataSlot (data)
Thread. SetData and Thread. GetData can be written and read in the slot.
Iv. data slot values are not shared between threads or context objects
The LocalDataStoreSlot structure can be used as a local storage memory mechanism. threads and contexts can use this mechanism to store thread-specific data and context-specific data respectively. When a common language is running, each process is assigned an array of Multi-slot data storage areas. The thread or context calls various functions to allocate data slots in the data storage area, store and retrieve data values in the slots, and release the data slots so that they can be reused after the threads or context expires.
Data slots are unique for each thread or context. Their values are not shared between threads or context objects. The data slot can be assigned by name or index number.
We can see from the following program
Imports System
Imports System. Threading
Module Module1
Sub Main ()
Dim mythread1 As Thread
Dim mythread2 As Thread
Dim mythread3 As Thread
Dim jg As LocalDataStoreSlot
'Create a thread object
Mythread1 = New Thread (AddressOf mythreadrun)
Mythread2 = New Thread (AddressOf mythreadrun)
Mythread3 = New Thread (AddressOf mythreadrun)
Console. WriteLine (Now. ToLongTimeString & "after the thread object is created, start the execution thread ")
'Jg = Thread. AllocateNamedDataSlot ("myjg ")
'Thread. SetData (jg, 100)
'Execution thread
Mythread1.Start ("thread 1 ")
Mythread2.Start ("thread 2 ")
Mythread3.Start ("thread 3 ")
'Wait for the thread to finish
Mythread1.Join ()
Mythread2.Join ()
Mythread3.Join ()
'Thread execution completed
Console. WriteLine (Now. ToLongTimeString & "finished thread execution! ")
Thread. FreeNamedDataSlot ("myjg ")
End Sub
Public Sub mythreadrun (ByVal data As Object)
Dim randomGenerator As New Random ()
Dim mynum As Integer
'Allocate a new slot that stores local thread data. The slot name is
'Myjg
Dim jg As LocalDataStoreSlot
Try
Jg = Thread. AllocateNamedDataSlot ("myjg ")
Catch
Jg = Thread. GetNamedDataSlot ("myjg ")
End Try
Thread. SetData (jg, 100)
Try
For mynum = 1 To 10
Thread. SetData (jg, Thread. GetData (jg)-mynum)
Console. writeLine (data & "& Now. toLongTimeString & "=>" & (Thread. getData (jg) + mynum) & "-" & mynum & ", the calculation result is:" & Thread. getData (jg ))
Thread. Sleep (randomGenerator. Next (10,200 ))
Next
Catch
Console. WriteLine (data & "& Now. ToLongTimeString &" thread terminated abnormally! ")
'Terminate the thread
Thread. CurrentThread. Abort ()
End Try
End Sub
End Module
All content of this blog is original, if reproduced please indicate the source http://blog.csdn.net/myhaspl/
To view the effect, I use a random number instead of a fixed sleep time, which is more expressive. The running result of the above program is as follows:
5. TLS Summary
1) TLS Basics
You can use the local storage area (TLS) of the hosting thread to store data exclusive to a certain line and application domain. . NET Framework provides two methods to use managed TLS: static fields and data slots related to threads. Thread-related static fields provide much better performance than the data slot, and enable the compile-time type check.
If you can predict your exact needs during compilation, use static fields related to the thread (Shared fields related to the thread in Visual Basic ). Static fields related to threads provide optimal performance. They also have the advantages of type check during compilation.
If you can only find your actual needs during running, use the data slot. The data slot is slower and more difficult to use than the static fields related to the thread, and the data is stored as the Object type. Therefore, it must be forcibly converted to the correct type for use.
2) Two TLS features a) whether it is using static fields related to threads or data slots, the data in TLS hosting is unique to the combination of threads and application domains.
Within the application domain, one thread cannot modify the data in another thread, even if the two threads use the same field or slot. When a thread accesses the same field or slot from multiple application domains, a separate value is maintained in each application domain. For example, if a thread sets the value of a thread-related static field, it then enters another application domain, and then retrieves the value of this field, the value retrieved in the second application domain is different from the value in the first application domain. Setting a new value for this field in the second application domain does not affect the value of this field in the first application domain. Similarly, when a thread obtains the same named data slot in two different application domains, the data in the first application domain will always be irrelevant to the data in the second application domain. B) if you know that some data is always exclusive to the combination of a thread and application domain, apply the ThreadStaticAttribute feature to the static field. Use this field like any other static field. The data in this field is exclusive to each thread that uses it. The performance of thread-related static fields is better than that of the data slot, and it has the advantage of checking the type during compilation. C) Please note that any class constructor code will run on the first thread in the first context accessing this field. In all other threads or contexts in the same application domain, if the fields are of the reference type, they will be initialized to null (Nothing in Visual Basic); If the fields are of the value type, they will be initialized as their default values. Therefore, you should not rely on the class constructor to initialize static fields related to the thread. Instead of initializing static fields related to the thread and assuming that they are initialized to null (Nothing) or their default values. D) In.. NET Framework 4, you can use System. threading. threadLocal (Of T) Class creates a local thread object. When this object is used for the first time, it will initialize it in an idle manner. This solves the problem mentioned in c. D). NET Framework provides a dynamic data slot exclusive to the combination of threads and application domains. There are two types of data slots: named slots and unnamed slots. Both are implemented by using the LocalDataStoreSlot structure. To create a named data slot, use the Thread. AllocateNamedDataSlot or Thread. GetNamedDataSlot method. To obtain a reference to an existing name slot, pass the name to the GetNamedDataSlot method. To create an unnamed data slot, use the Thread. AllocateDataSlot method. E) for the name slot and unnamed slot, use the Thread. SetData and Thread. GetData methods to set and retrieve information in the slot. These are static methods, which always act on the data of the threads currently executing them. F) The naming slot may be very convenient, because you can retrieve the slot by passing its name to the GetNamedDataSlot method when you need it, rather than maintaining reference to the unnamed slot. However, if another component uses the same name to name its thread-related storage zone, and a thread simultaneously executes code from your component and the component, the two components may destroy each other's data. (This scheme assumes that these two components run in the same application domain and they are not used to share the same data .) G) The thread uses the local storage memory mechanism to store thread-specific data. When a common language is running, each process is assigned an array of Multi-slot data storage areas. Threads can allocate data slots in the data storage area, store and retrieve data values in the slots, and release the slots after the threads expire for reuse. The data slot of each thread is unique. No other thread (even a subthread) can obtain the data.
1. debug the thread with a debugger
1) stack call
The following code is used as an example.
Imports System. Threading
Public Class Form1
Private Sub button#click (sender As System. Object, e As System. EventArgs) Handles Button1.Click
Dim main_x As Integer
Main_x = 5
Call sub1 (main_x)
End Sub
Private Sub sub1 (sub1_x As Integer)
Dim jg As Integer
Jg = sub1_x * sub1_x
Call sub2 (jg)
End Sub
Private Sub sub2 (sub2_x As Integer)
Dim jg As Integer
Jg = sub2_x * 2
'Set the breakpoint in the next sentence
Jg = jg * jg
End Sub
End Class
Let's first look at the call stack. Select the call stack from the Debug menu to see the call sequence of the process:
View the thread
Finally, check the local variables.
In addition, we can also study the stack situation when calling this thread. Through the disassembly code, select "go to disassembly" in the call Stack window"
Private Sub sub2 (sub2_x As Integer)
00000000 push ebp
00000001 mov ebp, esp
00000003 sub esp, 14 h
00000006 mov dword ptr [ebp-10h], ecx
00000009 mov dword ptr [ebp-4], edx
2017000c cmp dword ptr ds: [0256B1B8h], 0
00000013 je 0000001A
00000015 call 62A16743
2017001a xor edx, edx
2017001c mov dword ptr [ebp-8], edx
2017001f mov eax, dword ptr [ebp-10h]
00000022 mov dword ptr [ebp-14h], eax
00000025 mov ecx, dword ptr [ebp-10h]
00000028 call 628F5C25
2017002d mov dword ptr [ebp-0Ch], eax
00000030 push 32 h
00000032 mov edx, dword ptr [ebp-0Ch]
00000035 mov ecx, dword ptr [ebp-14h]
00000038 call FFDF30D0
2017003d mov ecx, dword ptr [ebp-4]
00000040 call FFFFFF70
00000045 mov ecx, 63 h
2017004a call FFDF2940
0000004f nop
Dim jg As Integer
Jg = sub2_x * 2
00000050 mov eax, dword ptr [ebp-4]
00000053 mov edx, 2
00000058 imul eax, eax, 2
2017005b jno 00000062
2017005d call 62A19A30
00000062 mov dword ptr [ebp-8], eax
'Set the breakpoint in the next sentence
Jg = jg * jg
00000065 mov eax, dword ptr [ebp-8]
00000068 imul eax, dword ptr [ebp-8]
2017006c jno 00000073
2017006e call 62A19A30
00000073 mov dword ptr [ebp-8], eax
End Sub
00000076 nop
00000077 nop
00000078 mov ecx, 63 h
2017007d call FFDF2A60
00000082 nop
00000083 mov esp, ebp
00000085 pop ebp
00000086 ret
ESP is the top pointer of the stack.
Ebp is the base address pointer.
+ ----- +
+ Base address +
+ ----- +
+ Stack content +
+ Stack content +
+ Stack content +
+ Stack content +
+ Stack content +
+ Stack top +
As shown in, the address of the base is larger than the address on the top of the stack, that is, the address increases downward.
Registers ebp and esp store the current base address and stack top address
First, when you enter the Function
00000000 push ebp
Backup base address pointer
00000001 mov ebp, esp
Then set the base address pointer to point to the top of the stack, which is equivalent to clearing the content of the current stack and preparing to allocate local variables in the stack.
00000003 sub esp, 14 h
Complete the space allocation of the stack (which can be understood as an accessible stack of this function), and increase the stack top pointer by 14 h (downward growth means that the stack space growth pattern is address decrease ). It is equivalent to the space already in the stack for 14 h.
Dim jg As Integer
Jg = sub2_x * 2
00000050 mov eax, dword ptr [ebp-4]
00000053 mov edx, 2
00000058 imul eax, eax, 2
2017005b jno 00000062
2017005d call 617391D0
00000062 mov dword ptr [ebp-8], eax
'Set the breakpoint in the next sentence
Jg = jg * jg
00000065 mov eax, dword ptr [ebp-8]
00000068 imul eax, dword ptr [ebp-8]
2017006c jno 00000073
2017006e call 617391D0
00000073 mov dword ptr [ebp-8], eax
The above Code shows that
Sub2_x is allocated in the dword ptr [ebp-4], while the jg is allocated in the dword ptr [ebp-8]
Finally, when the function is left, the pointer to the stack before the function is restored, which is equivalent to releasing the space allocated in the stack.
End Sub
00000083 mov esp, ebp
Restore stack top pointer
00000085 pop ebp
Restore base address pointer
00000086 ret
2. Modify the default stack size.
Dim Thread variable name As Thread = New Thread (function name, stack size in bytes)
For example
Dim mythread As Thread = New Thread (myfun, 1024*512)
Allocated kb bytes