Windows core programming Note (7)----thread synchronization in kernel mode

Source: Internet
Author: User
Tags semaphore terminates unique id

1. Synchronization between kernel objects and user modethe only disadvantage of using kernel objects is performance, when invoking kernel object functions, the calling thread must switch from user mode to kernel mode, which is quite
Time-consuming.
The kernel object (process, thread, job) is either in a triggered state or is not in a triggered condition. The process kernel object is always created without a trigger state.
When the process terminates, the operating system automatically turns the process kernel object into a trigger state. This state is always maintained when the process kernel object is in a triggered state.
Can no longer be turned back to the non-triggering state.
2. Wait for kernel objectWaitForSingleObject waits for a single Kernel object, Waitformultipleobject waits for multiple kernel objects, and supports up to maximum_wait_objects simultaneously
(64) A kernel object.
Waitformultipleobject wait for one of the multiple kernel objects to trigger, the return value if neither Wait_timeout nor wait_failed, then use the
The return value minus WAIT_OBJECT_0 is the index value of the kernel object that has been triggered.
3. Create an event view MSDN
HANDLE WINAPI createevent (
__in          lpsecurity_attributes lpeventattributes,
__in          bool bManualReset,
__in          bool binitialstate,
__in          LPC Tstr lpname
);
Bmanualreset: if the event-triggering state is set manually, False is automatically set by the system.
Binitialstate: whether the state is initialized, true if the event is a trigger state, or false is not triggered
Lpname: The event name, nullable, or an event handle with event_all_access permission if the event name has already been created.
methods in other processes to access the event object: Use inheritance, use DuplicateHandle, call OpenEvent to open an event with the specified name
to change the event status:
setevent set event to trigger status
resetevent set event to not trigger status
4. Can wait for Timer kernel objectCreateWaitableTimer the kernel object is not triggered when the creation is complete, you need to use the API
BOOL WINAPI SetWaitableTimer (
__in HANDLE Htimer,
__in Const large_integer* Pduetime,
__in LONG Lperiod,
__in Ptimerapcroutine Pfncompletionroutine,
__in LPVoid Lpargtocompletionroutine,
__in BOOL Fresume
);
To set some properties of the timer object, Pduetime is the first trigger time (UTC time), and Lperiod indicates that the timer should be after the first trigger
Trigger at what frequency.
5. Signal VolumeCreating Semaphore Kernel Objects
HANDLE WINAPI CreateSemaphore (
__in Lpsecurity_attributes Lpsemaphoreattributes,
__in LONG lInitialCount,
__in LONG lMaximumCount,
__in LPCTSTR lpname
);
lInitialCount the number of available resources for the specified semaphore, lMaximumCount represents the maximum resource count for the semaphore
The rules for semaphores are as follows:
1, if the current resource count is greater than 0, then the semaphore is in the trigger state;
2, if the current resource count equals 0, then the semaphore is in the non-triggering state;
3, the system will not let the current resource count is less than 0;
4, the current resource count is never greater than the maximum number of resources.
6. Mutex ObjectA mutex object contains a reference count, a thread ID, and a recursive count. The thread ID is used to record the ID of the thread currently occupying this mutex, and the recursive count is used to denote the
The number of times the thread occupies the mutex.
The mutex object differs from the critical section:
The mutex is the kernel object, and the critical section is synchronized in user mode, which means that the mutex is slower than the critical section and the threads in different processes can access the same mutex.
A thread can specify a wait time when it waits for access to a resource.
By the way, the difference between user mode and kernel mode is:
1. The application runs in user mode, and the operating system core component runs in kernel mode. Multiple drivers run in the kernel mode, but some drivers
Run in user mode;
2. When a user-mode application is started, Windows creates a process for the program, and the process provides the application with its own "virtual address space" and a dedicated "handle table"
Because the application's virtual address space is private, an application cannot change data that belongs to other applications.
3. All code running in kernel mode shares a single virtual address space, and if the kernel-mode driver is corrupted, the entire operating system becomes corrupted.
Create
HANDLE WINAPI CreateMutex (
__in Lpsecurity_attributes Lpmutexattributes,
__in BOOL Binitialowner,
__in LPCTSTR lpname
);
Binitialowner controls the initial state of the mutex, and if passed false, the thread ID and recursive count of the mutex object are set to 0.
means that the mutex is not occupied by any thread and therefore is in a triggered state, and the thread ID of the object is set to the ID of the calling thread.
The recursive technique will be set to 1. Because the thread ID is not 0, the mutex is not in the triggered state.


The mutex differs from other kernel objects in that it has "thread ownership". When a thread calls ReleaseMutex, the function checks the ID of the calling thread and the ID of the mutex that is stored internally
If inconsistent, the function does nothing to return Fasle (the mutex you are trying to release does not belong to the caller).
If a thread that occupies a mutex terminates before releasing the mutex, the system considers the mutex to be abandoned. After the mutex is abandoned, the system sets the ID of the mutex object to 0, and its
The recursive count is set to 0. It then detects if there are other threads waiting on the mutex, and if so, dispatches the thread.
7. Other thread synchronization functions1, the asynchronous device i\o, the device object is a synchronized kernel object, you can use WaitForSingleObject and incoming file handle, socket, communication port and so on. System execution
When asynchronous i\o, the device object is not triggered, and once the i\o operation is complete, the device object is triggered.
2, WaitForInputIdle, waits for the specified process to know that there are no pending inputs in the thread that created the first window of the application. Used primarily when a parent process creates a child process.
3, Waitfordebugevent
4. The singleobjectandwait function triggers a kernel object and waits for another kernel object.
DWORD WINAPI signalobjectandwait (
_in_ HANDLE hobjecttosignal,
_in_ HANDLE Hobjecttowaiton,
_in_ DWORD dwmilliseconds,
_in_ BOOL balertable
);
Hobjecttosignal: The kernel object handle that needs to be triggered can only be a mutex, semaphore, or event, and any other object will cause the function to return an error;
Hobjecttowaiton: A handle to the kernel object that waits, which can be a mutex, semaphore, event, timer, process, thread, job console input, and change notification;
Balertable: Whether the asynchronous procedure call added to the queue can be processed when the thread is in a wait state. (whether APC callbacks can be performed)
The advantage is that executing a function is more efficient than two functions, and switching from user mode to kernel mode consumes a lot of CPU events, and the scheduling of threads is time consuming.
The code consumes a lot of CPU time
ReleaseMutex (Hmutex);
WaitForSingleObject (hevent, INFINITE);

Use signalobjectandwait to replace these two lines of code. In high-performance server applications, signalobjectandwait can save a lot of processing time.

Test code:
HANDLE g_ Hsemaphore;volatile LONG g_nthreadindex = 0; UINT WINAPI helpthread (lpvoid lpparam) {//here gives each thread a unique ID to identify InterlockedExchangeAdd (&g_nthreadindex, 1); int Ncurindex = g_nthreadindex;cout<< "into thread, thread id=" <<nCurIndex<<endl; WaitForSingleObject (G_hsemaphore, INFINITE);cout<< "thread" <<nCurIndex<< "get semaphore resource ..." <<endl; " int i = 0;while (i<2) {i++;cout<< "Threads" <<nCurIndex<< "in the middle of a task ..." <<endl; Sleep (1000);} LONG lprevcount;//semaphore resource is used, released, so that the other waiting thread to continue execution ReleaseSemaphore (G_hsemaphore, 1, &lprevcount);//The resource count of the semaphore + 1, return the value of the previous resource Count cout<< "Previous resource count is" <<lPrevCount<< "free semaphore resource, thread" <<nCurIndex<< "Exit ..." < <endl;return 0;} Voidsemaphoretest () {//create semaphore G_hsemaphore = CreateSemaphore (null, 3, 4, NULL); HANDLE Hthreads[6];int i = 0; 
<span style= "white-space:pre" ></span>//test multiple threads preemption semaphore resource for (; i<6; ++i) {hthreads[i] = (HANDLE) _ Beginthreadex (null, 0, helpthread, NULL, 0, NULL);} WaitForMultipleObjects (6, Hthreads, TRUE, INFINITE);//close thread handle for (i=0; i<6; ++i) CloseHandle (Hthreads[i]);cout< < "worker threads executed ..." <<endl;//any process can use OpenSemaphore to get an already existing semaphore handle that is associated with the current process, and that is related to a DWORD dwret = WaitForSingleObject (G_hsemaphore, 5*1000); switch (dwret) {case wait_object_0:cout<< "semaphore is available ..." <<endl; Break;case wait_timeout:cout<< "Wait for timeout ..." <<endl;break;case wait_failed:cout<< ". WaitForSingleObject call failed with system error code:%u "<<getlasterror () <<endl;break;} OpenSemaphore () CloseHandle (G_hsemaphore);} UINT __stdcall Mutexhelpthread (lpvoid lpparam) {HANDLE Hmutex = (HANDLE) Lpparam;dword dwret = WaitForSingleObject (HMutex , INFINITE);cout<< "Mutex object Trigger" <<endl;return 0;} Voidmutextest () {HANDLE Hmutex = CreateMutex (null, TRUE, NULL); HANDLE hthread = (HANDLE) _beginthreadex (NULL, 0, Mutexhelpthread, (LPVOID) Hmutex, 0, NULL);//release mutex to avoid two threads waiting for deadlock ReleaseMutex (Hmutex); WaitForSingleObject (Hthread, INFINITE); CloseHandle (hthread);D Word dwret = WaitForSingleObject (Hmutex, INFINITE); switch (dwret) {case wait_object_0:break; Case Wait_timeout:break;case Wait_failed:break;} CloseHandle (Hmutex);}


Windows core programming Note (7)----thread synchronization in kernel mode

Related Article

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.