- UID
- 3808
- 精华
- 积分
- 1480
- 威望
- 点
- 宅币
- 个
- 贡献
- 次
- 宅之契约
- 份
- 最后登录
- 1970-1-1
- 在线时间
- 小时
|
发表于 2020-1-27 18:55:09
|
显示全部楼层
小弟我简单根据本帖子上的api指导和win32sdk编程中的多线程程序写了一个win7 x64的互斥锁的多线程内核程序的例子,为了便于理解,小弟写了一个python的程序作为对应。
例子采用互斥锁的应用中的给共享资源(这里以一个全局变量为例)进行计数来说明互斥锁的应用,其具体原理就是本帖子中说明的堵塞和解堵塞的原理。
python程序(python 3.7 amd64)
- import threading
- import time
- # global parameter.
- g_num = 0
- def thread1(num):
- global g_num
- mutex.acquire()
-
- for i in range(num):
- g_num += 1
- mutex.release()
- print("thread 1: g_num=%d" % g_num)
-
- def thread2(num):
- global g_num
- mutex.acquire()
-
- for i in range(num):
- g_num += 1
- mutex.release()
- print("thread 2: g_num=%d" % g_num)
- # Create a mutex lock, and the defaulted is unlocked.
- mutex = threading.Lock()
- def main():
- th1 = threading.Thread(target=thread1, args=(10000000,))
- th2 = threading.Thread(target=thread2, args=(10000000,))
- th1.start()
-
- th2.start()
- time.sleep(3)
-
- if __name__ == '__main__':
- main()
-
复制代码
运行结果:
C语言 win7 x64 内核程序:
- #include <wdm.h>
- #include <windef.h>
- // Global parameter.
- unsigned long g_number = 0;
- void thread1(void *mutex)
- {
- unsigned long i;
- PKMUTEX pkMutex = (PKMUTEX)mutex;
- KeWaitForSingleObject(pkMutex,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- DbgPrint("This is Thread 1...\n");
- for (i = 0; i < 10000000; i++)
- {
- g_number++;
- }
- KeReleaseMutex(pkMutex, FALSE);
- // Print the result of g_number in thread 1.
- DbgPrint("Thread 1:g_number = %ld\n", g_number);
- PsTerminateSystemThread(STATUS_SUCCESS);
- }
- void thread2(void *mutex)
- {
- unsigned long i;
- PKMUTEX pkMutex = (PKMUTEX)mutex;
- KeWaitForSingleObject(pkMutex,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- DbgPrint("This is Thread 2...\n");
- for (i = 0; i < 10000000; i++)
- {
- g_number++;
- }
- KeReleaseMutex(pkMutex, FALSE);
- // Print the result of g_number in thread 2.
- DbgPrint("Thread 2:g_number = %ld\n", g_number);
- PsTerminateSystemThread(STATUS_SUCCESS);
- }
- void DriverUnload(IN PDRIVER_OBJECT pDrvObj)
- {
- DbgPrint("DriverUnload....\n");
- }
- NTSTATUS DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING RegistryPath)
- {
- NTSTATUS status = STATUS_SUCCESS;
- pDrvObj->DriverUnload = DriverUnload;
- // TODO: mutex-lock thread test.
- HANDLE hThread1, hThread2;
- KMUTEX mutex;
- // Create the mutex lock.
- KeInitializeMutex(&mutex, 0);
- // Create the thread.
- PsCreateSystemThread(&hThread1,
- 0,
- NULL,
- NtCurrentProcess(),
- NULL,
- thread1, // thread proc
- &mutex);
- PsCreateSystemThread(&hThread2,
- 0,
- NULL,
- NtCurrentProcess(),
- NULL,
- thread2, // thread2 proc
- &mutex);
- void *Queue[2];
- ObReferenceObjectByHandle(hThread1,
- 0,
- NULL,
- KernelMode,
- &Queue[0],
- NULL);
- ObReferenceObjectByHandle(hThread2,
- 0,
- NULL,
- KernelMode,
- &Queue[1],
- NULL);
-
- KeWaitForMultipleObjects(2,
- Queue,
- WaitAll,
- Executive,
- KernelMode,
- FALSE,
- NULL,
- NULL);
- // Subtract the count the object reference and
- // release the system resources.
- ObDereferenceObject(Queue[0]);
- ObDereferenceObject(Queue[1]);
- // Sleep 2 seconds, wait for the threads completely
- // finish their work.
- LARGE_INTEGER sleep;
- sleep.QuadPart = -20 * 1000 * 1000;
- KeDelayExecutionThread(KernelMode,
- FALSE,
- &sleep);
- DbgPrint("The process is terminated...\n");
- return status;
- }
复制代码
运行结果:
|
|