TLS in DLL

Source: Internet
Author: User

Thread Local variable introduction can solve the problem of non-synchronization of static or global variables modified by multiple threads.

For a simple example, a function FN may need to modify a static variable. The intention of writing this function is to call the function in its own thread, but if other threads may call this function, the value of this static variable may be damaged. Use local variables of the thread to ensure that each thread uses its own copy and does not interfere with each other.

Here, you need to pay attention to some issues about TLS. For example, _ declspec (thread) can only be used to define static or global variables. It cannot act on classes, but can act on class objects. Note the local variables in the DLL. If _ declspec (thread) is used in the DLL to define a local variable of the thread and the DLL is dynamically loaded with loadlibarary, an access error occurs. Because the local variables of the thread are created at runtime, there is no additional space (or how much space is reserved) after loadlibrary is loaded into the DLL to store the local variables of the thread, an access error occurs.

If your DLL uses _ declspec (thread) to define a local variable of the thread, make sure that your DLL is statically loaded. If you cannot guarantee this, you 'd better use the tls api to create local variables for the thread.

 

The last section of the loadlibrary function in msdn is as follows:

The Visual C ++ compiler supports a syntax that enables you to declare
Thread-local variables:_ Declspec (thread). If you use this syntax in
DLL, you will not be able to load the DLL explicitly usingLoadlibraryOr
LoadLibraryEx. If your dll will be loaded
Explicitly, you must use the thread local storage functions instead
_ Declspec (thread).

 

Like dynamic and dynamic t l s, static t l s can also associate data with threads. However, static t l s is much easier to use in code, because it can be used without calling any function.

For example, you want to associate the start time with every thread created by the application. You only need to declare the start time variable as follows:

 

_ Declspec (thread) DWORD gt_dwstarttime = 0;

_ D e c l s p e c (t h r e a D) the prefix is a modifier that m I c r o s o f t is added to the Visual C ++ compiler. It tells the compiler that the corresponding variables should be put into the executable file or its own section in the d l file. _ D e c l s p e c (t h r e a d) must be declared as a global or static variable in the function (or outside the function. A local variable of the Type _ d e c l s p e c (t h r e a d) cannot be declared. This shouldn't be a problem, because local variables are always associated with specific threads. I use the prefix G T _ for the global T L S variable, and the S T _ for the static T L S variable.

When the compiler compiles a program, it puts all the t l s variables into their own sections. The name of this section is. t l s. The linking Program combines all. t l s sections from all object modules to form a result executable file or a large. t l s section in the d l file.

To make the static t l s run, the operating system must be involved in the operation. When your application is loaded into the memory, the system will look for. t l s section, and dynamically allocate a large enough memory block to store all the static t l s variables. Every time the Code in your application references a variable, it is converted to a memory location contained in the allocated memory block. Therefore, the compiler must generate some auxiliary code to reference the static t l s variable, which will make your application relatively large and run slowly. On an x86 CPU, three auxiliary machine commands are generated for each referenced static t l s variable.

If another thread is created in the process, the system will capture it and automatically allocate another memory block to store the static t l s variable of the new thread. The new thread only has access to its own static t l s variable and cannot access the t l s variable belonging to other threads.

This is how the static t l s variable runs. Now let's take a look at the situation of d l. Your application is likely to use the static t l s variable and link to a d l variable that also wants to use the static t l s variable. When the system loads your application, it must first determine the application's. t l s section size, and link this value to any of the d l in your application. the size of the t l s section. When you create a thread in your process, the system automatically allocates enough memory blocks to store all the t l s variables required by the application and all the hidden links d L.

Next let's take a look at when the application calls l o a d l I B R A R Y to link to a d l that also contains a static T L S variable, what will happen. The system must view all existing threads in the process and expand their t l s memory blocks to meet the memory requirements of the new d L. In addition, if f r e l I B R A R Y is called to release d l containing the static T L S variable, the memory blocks related to each thread in the process should be compressed.

Such a management task is too heavy for the operating system. Although the system allows libraries containing static t l s variables to be explicitly loaded at runtime, t l s data is not initialized accordingly. If you try to access the data, it may lead to access violations. This is the only drawback of using static t l s. This problem does not occur when dynamic t l s is used. The dynamic t l s library can be loaded at runtime and released at runtime without any problems.

 

If _ declspec (thread) is used in the DLL to define a local variable of the static thread and the DLL is dynamically loaded, access to the local variable of the thread will be abnormal. However, it is easy to locate this issue. Check if the error is caused by an access error to the local variable of this thread, and then go to the assembly code to see the TLS-like words, for example, the following assembly code:

G_count = 100; <br/> 00cc19ce mov eax, dword ptr [_ tls_index (0cc7250h)] <br/> 00cc19d3 mov ECx, dword ptr fs: [2ch] <br/> 00cc19da mov edX, dword ptr [ECx + eax * 4] <br/> 00cc19dd mov dword ptr [edX + 104 H], 64 h 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.