当前位置:网站首页>Multithreading programming under Win32 API
Multithreading programming under Win32 API
2022-07-25 06:07:00 【N-order magic cube】
1. use Win32 Function to create and terminate threads
Win32 The function library provides functions for multithreading operation , Including creating threads 、 Thread termination 、 Establish mutually exclusive zones, etc . The function to create a new thread in the main thread or other active threads of the application is as follows :
HANDLE CreateThread(
lpThreadAttributes: Pointer; { Security Settings }
dwStackSize: DWORD; { Stack size }
lpStartAddress: TFNThreadStartRoutine; { Entry function }
lpParameter: Pointer; { Function parameter }
dwCreationFlags: DWORD; { Startup options }
var lpThreadId: DWORD { Output thread ID }
)
//-----------------------------------------------------
CreateThread( Introduction to six parameters ) Click to open the link
//-----------------------------------------------------
If the creation is successful, the handle to the thread is returned , Otherwise return to NULL. After creating a new thread , The thread starts execution . But if dwCreationFlags Used in CREATE_SUSPENDED characteristic , Then the thread does not execute immediately , But hang up first , Wait until call ResumeThread Before starting the thread , In this process, you can call the following function to set the priority of the thread :
BOOL SetThreadPriority(HANDLE hThread,int nPriority);
When the function of the calling thread returns , The thread terminates automatically .
If you need to terminate during the execution of the thread, you can call the function :
VOID ExitThread(DWORD dwExitCode);If the thread is terminated outside the thread , Then you can call the following function :
BOOL TerminateThread(HANDLE hThread,DWORD dwExitCode);
But we should pay attention to it. : This function may cause system instability , And the resources occupied by threads are not released . therefore , In general , It is not recommended to use this function .
If the thread to be terminated is the last thread in the process , After the thread is terminated, the corresponding process should also be terminated .
2. Synchronization of threads
In the thread body , If the thread is completely independent , There is no conflict with other threads in resource operations such as data access , You can program according to the usual single thread method . however , This is often not the case when multithreading , Threads often access some resources at the same time . It is inevitable to cause conflicts due to access to shared resources , To solve this thread synchronization problem ,Win32 API A variety of synchronization control objects are provided to help programmers solve shared resource access conflicts . Before introducing these synchronization objects, let's first introduce the wait function , Because this function is used for access control of all control objects .
Win32 API Provides a set of wait functions that enable a thread to block its own execution . These functions generate signals in one or more synchronization objects in their parameters , Or it will return after the specified waiting time . When the waiting function does not return , The thread is in a wait state , At this time, the thread only consumes very little CPU Time . Using the wait function can ensure the synchronization of threads , It can also improve the operation efficiency of the program . The most commonly used wait function is :
DWORD WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds);
The function WaitForMultipleObject It can be used to monitor multiple synchronization objects at the same time , The declaration of this function is :
DWORD WaitForMultipleObject(DWORD nCount,CONST HANDLE *lpHandles,BOOL bWaitAll,DWORD dwMilliseconds);
(1) Mutex object
Mutex The state of an object is signaled only when it is not owned by any thread , And when it is owned, there is no signal .Mutex Object is very suitable for coordinating the mutually exclusive access of multiple threads to shared resources . You can use this object as follows :
First , Create a mutex object , Get the handle :
HANDLE CreateMutex();
then , In front of areas where threads may conflict ( That is, before accessing shared resources ) call WaitForSingleObject, Pass the handle to the function , Request to occupy mutually exclusive objects :
dwWaitResult = WaitForSingleObject(hMutex,5000L);
End of shared resource access , Release the occupation of mutex objects :
ReleaseMutex(hMutex);Mutex objects can only be occupied by one thread at a time , When the mutex object is occupied by a thread , If there is another way to occupy it , You must wait until the previous thread is released to succeed .
(2) Signal object
Signal objects allow simultaneous access to shared resources of multiple threads , Specify the maximum number of threads that can be accessed simultaneously when creating an object . When a thread successfully requests access , The counter in the signal object is decremented by one , call ReleaseSemaphore After the function , The counter in the signal object is incremented by one . among , The counter value is greater than or equal to 0, But less than or equal to the maximum value specified at creation . If an application is creating a signal object , Set the initial value of its counter to 0, It blocks other threads , Protected resources . After initialization , call ReleaseSemaphore Function increases its counter to the maximum , Normal access . You can use this object as follows :
First , Create a signal object :
HANDLE CreateSemaphore();
Or open a signal object :
HANDLE OpenSemaphore();
then , Call before the thread accesses the shared resource WaitForSingleObject.
After the shared resource access is completed , The occupation of the signal object should be released :ReleaseSemaphore();
(3) Event object
Event object (Event) Is the simplest synchronization object , It includes two states of signal and no signal . Before a thread accesses a resource , Need to wait for an event to happen , At this time, the event object is the most appropriate . for example : Only after the communication port buffer receives data , The monitoring thread is activated .
The event object is CreateEvent Function . This function can specify the class of the event object and the initial state of the event . If it is a manual reset event , Then it always keeps the signal state , Until you use ResetEvent The function is reset to an event without a signal . If it's an automatic reset event , Then its state will automatically change to no signal after a single waiting thread is released . use SetEvent You can set the event object to a signaled state . When creating events , You can name objects , In this way, threads in other processes can use OpenEvent Function to open the event object handle with the specified name .HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes, // SECURITY_ATTRIBUTES Structure pointer , for NULL
BOOL bManualReset, // Manual / Automatically
// TRUE: stay WaitForSingleObject Must be called manually after ResetEvent Clear the signal
// FALSE: stay WaitForSingleObject after , The system automatically clears the event signal
BOOL bInitialState, // The initial state
LPCTSTR lpName // Name of event
)
Use " event " The mechanism should pay attention to the following matters: :
(1) If events are accessed across processes , The event must be named , When naming Events , Be careful not to conflict with other global named objects in the system namespace ;
(2) Whether the event should be automatically recovered ;
(3) The initial state of the event is set .
(4) Exclusion zone object
When executing asynchronously in the exclusion zone , It can only share resource processing between threads of the same process . Although at this time, the above methods can be used , however , The method of using exclusion zone makes the efficiency of synchronous management higher .
Define a CRITICAL_SECTION The exclusion zone object of the structure , Call the following functions to initialize the object before the process uses :
VOID InitializeCriticalSection(LPCRITICAL_SECTION);
When a thread uses exclusion zones , Call function :EnterCriticalSection perhaps TryEnterCriticalSection;
When it is required to occupy 、 When exiting the exclusion zone , Call function LeaveCriticalSection, Release the occupation of exclusion zone objects , For other threads
边栏推荐
- sqlilabs less-28~less-8a
- Unity animator animation and state machine
- (Niuke multi School II) j-link with arithmetic progress (least square method / three points)
- Analyzing the principle of DNS resolution in kubernetes cluster
- Req.body in node.express is always undefind
- Run length test of R language: use the runs.test function to perform run length test on binary sequence data (check whether the sequence is random)
- 计算BDP值和wnd值
- Unity Animator动画与状态机
- 嵌入式c语言开发之宏定义求两个数的最大值的使用技巧
- Codeforces Round #809 (Div. 2)
猜你喜欢

HTB-Devel

Softing pngate series gateway: integrate PROFIBUS bus into PROFINET network

sqlilabs less-29

剑指 Offer 54. 二叉搜索树的第k大节点

(牛客多校二)J-Link with Arithmetic Progression(最小二乘法/三分)

sqlilabs less-28~less-8a

sqlilabs less-28~less-8a

剑指 Offer 36. 二叉搜索树与双向链表

Softing pnGate系列网关:将PROFIBUS总线集成到PROFINET网络

Sword finger offer 45. arrange the array into the smallest number
随机推荐
有什么能在网上挣钱的项目啊?做自媒体靠谱吗?
y76.第四章 Prometheus大厂监控体系及实战 -- prometheus进阶(七)
Baidu, Alibaba, Tencent, who fell first?
(2022 Niuke multi school) D-Link with game glitch (SPFA)
(15)[驱动开发]过写拷贝
VIM configuring golang development environment
暑期总结2
(15) [driver development] over written copy
Vim配置Golang开发环境
10、渲染基础
【Node】服务端口被占用Error: listen EADDRINUSE: address already in use :::9000-如何关闭node启动的端口
SAP FICO section III BDC and ltmc import S4 financial account
Productivity tool in the new era -- flowus information flow comprehensive evaluation
Pdf snapshot artifact
(16) [system call] track system call (3 rings)
ROI pooling and ROI align
sqlilabs less-29
[typescript manual]
动态规划学习笔记
sqlilabs less-29