How many Wanda platform executives? What is the strength of the Wanda platform director?

How many Wanda platform executives? What is the strength of the Wanda platform director? -Supervisor σσ [61806] Identify Lao An Q [61806] "Excellent_Quality_Ping_Taiwan" "_" "Set_Top_wait_Meet" "One Step"

  A common feature of DLL is that there is an initialization function, a resource release function, and several other functions are core functions. And these DLLs are sometimes called by multiple processes at the same time, which involves the problem of multi-threaded DLL calling by multiple processes. It's a bit circumvent. According to the problems I encountered in practice, I will share my experience in solving such problems in four situations:
  
  1. The dynamic library has only one exported function.
  
  This situation is very rare and the easiest to handle. When writing functions in this case, you only need to consider that there is no conflicting global data. The global data here includes data blocks and static global variables allocated in the heap. If such global data exists, then different threads in the process accessing this function will cause conflicts.
  
  The solution is also very simple, is to try to use the stack (stack) to solve the problem. Since the owner of the stack is a thread, it must be thread-safe. Of course, we must pay attention to avoid stack overflow.
  
  We all know that if you want to retain the state of the previous call when the function is called again, you can use static variables. But if you want to keep the thread safe of the function, then static variables cannot be used, because static variables are global and belong to the process, which is shared by threads within the process. So if you really need to maintain the state of the function in the same thread, which is equivalent to passing parameters between different calls, you can consider using a static global thread local variable, that is:
  
  __declspec (thread) int tls_i = 1;
  
  this variable definition makes the compiler It is guaranteed that tls_i corresponds to each thread, that is, each thread has a copy of tls_i, which is necessarily thread-safe.
  
  2. The dynamic library exports multiple functions, and there is data transfer between the multiple functions.
  
  As mentioned earlier, generally DLLs export multiple functions, one for initialization, one for resource release, and the other for core functions. There is a high possibility of data transfer between these functions. If an initialization function is called in thread A, and the core function function is called in thread B, then the resources of thread A's initialization function cannot correspond to the core function in thread B, in addition to the data between core function functions Passing, such a DLL is not thread safe and will inevitably lead to errors.
  
  The solution is for the user (that is, the person using the DLL) to ensure that these exported functions are called in one thread. But this will greatly limit the design of the interface and the user's freedom of use. So the best way is for functions to take care of their own thread safety. Different functions use dynamic TLS for data transfer and thread local storage.
  
  For example:
  
  I have defined a variable globally to store the index ID stored locally by the current thread.
  
  __declspec (thread) int tls_i = 1;
  
  when calling the function that allocates resources, call the dynamic TLS function TlsAlloc, assign an ID, record it in the global thread-safe tls_i variable, and save the data in the thread-safe through the TlsSetValue function Area; when calling the function to obtain a resource, obtain the resource through TlsGetValue. After the processing is completed, call Tlsfree to release the TLS index so that the new thread can occupy it.
  
  In this way, as long as each function in the DLL guarantees that its part is thread-safe, passing data between functions through TLS (static and dynamic), you can achieve thread-safety of the entire DLL.
  
  3. Limit the number of threads accessing a function in the DLL.
  
  Sometimes, the number of access threads for a function in the DLL is limited. If the limit is exceeded, other threads have to wait for a certain amount of time. If a certain time elapses and the execution opportunity cannot be obtained, a timeout is returned. This design is user-friendly and very practical. Some commercial programs are indeed priced according to the number of channels that users are allowed to access.
  
  To do such a encapsulation of the functions in the DLL, it is generally simple to use Semaphore semaphores to solve. When the DLL is initialized, the CreateSemaphore function is called to initialize the semaphore. The prototype is as follows:
  
  HANDLE CreateSemaphore (
  
  LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
  
  // pointer to security attributes
  
  LONG lInitialCount, // initial count
  
  LONG lMaximumCount, // maximum count
  
  LPCTSTR lpName // pointer to semaphore- object name
  
  );
  
  for the semaphore, it will decrement its state value (an integer) by 1 every time WaitForSingleObject (of course to enter), and use ReleaseSemaphore to increase its state value by 1, when its state value is 0 From signal to no signal. Using this feature of semaphores, we set the initial value of the semaphore (the second parameter) to the limited number of thread accesses during initialization. Within the function to limit the number of access threads, call WaitForSingleOject to obtain control, and specify a waiting time (this is specified by the configuration file), return according to the situation timeout, use ReleaseSemaphore to release the occupation, so that other threads can call this function.
  
  4. Multi-thread safe DLL under multi-process situation.
  
  Earlier 3 said that sometimes it is necessary to restrict the access thread of a certain function, and we know that DLL can be loaded and called by multiple. That is to say, if we limit only one process, then in the case of multiple process calls, such a limit is easily broken.
  
  We all know that the Semaphore semaphore belongs to the kernel object, which means that it can be shared and accessed by multiple processes, that is, if we assign a name to a Semaphore, in another process, we only need to call the OpenSemaphore function with the same name You can access it by turning on the semaphore. So the problem is solved?
  
  The reality is that in the case of multiple processes, it is generally not a simple multi-process sharing a Semaphore. A lot of information needs to be communicated between multiple processes. The general solution is to use shared data segments.
  
  #pragma data_seg ("share")
  
  int share_data = 0; // It needs to be initialized, otherwise the global variable will be placed in the BSS section, which will lead to sharing failure
  
  #pragma data_seg ()
  
  #pragma comment (linker, "/ SECTION: share, RWS ") // If you don't add this sentence, it simply means that they are put in the data segment, and there is no sharing.
  
  A shared data segment named share is generated by the pragam compiler instruction, so that the variable share_data can be shared by multiple processes. Yes. If you want to exchange data between multiple processes, just add the data definition in data_seg.

Guess you like

Origin www.cnblogs.com/ycyhjj2865/p/12735352.html