阅读:1739回复:10
请教系统线程无法退出的问题
请教系统线程无法退出的问题
我用的是walteonly的例子 typedef struct _DEVICE_EXTENSION { ... KEVENT evKill; PKTHREAD thread; }; NTSTATUS StartThread(PDEVICE_EXTENSION pdx) { NTSTATUS status; HANDLE hthread; KeInitializeEvent(&pdx->evKill, NotificationEvent, FALSE); status = PsCreateSystemThread(&hthread, THREAD_ALL_ACCESS, NULL, NULL, NULL, (PKSTART_ROUTINE) ThreadProc, pdx); if (!NT_SUCCESS(status)) return status; ObReferenceObjectByHandle(hthread, THREAD_ALL_ACCESS, NULL, KernelMode, (PVOID*) &pdx->thread, NULL); ZwClose(hthread); return STATUS_SUCCESS; } VOID StopThread(PDEVICE_EXTENSION pdx) { KeSetEvent( &pdx->evKill, 0, FALSE); KeWaitForSingleObject(pdx->thread, Executive, KernelMode, FALSE, NULL); ObDereferenceObject(pdx->thread); } VOID ThreadProc(PDEVICE_EXTENSION pdx) { while(TRUE) { //采集数据 } KeWaitForSingleObject(&pdx->evKill, Executive, KernelMode, FALSE, NULL);//这里我用的对不对呢。 PsTerminateSystemThread(STATUS_SUCCESS); } 我在IRP_MN_START_DEVICE请求时创建系统线程。当收到一个PnP请求IRP_MN_STOP_DEVICE或IRP_MN_REMOVE_DEVICE时终止该线程。 现在的问题是终止时PsTerminateSystemThread(STATUS_SUCCESS);好像不执行,如何知道系统线程已经结束了呢。 |
|
沙发#
发布于:2003-10-09 11:49
是不是
while(TRUE) { //采集数据 } 没有退出??可以在PsTerminateSystemThread加个打印语句看看 |
|
论坛版主
![]() |
板凳#
发布于:2003-10-09 16:06
:)你后面的等待和shut线程的语句能执行到?你的死循环退不出来的嘛!把死循环改了三,可以设个标志,比如:
bool stop = false; while(!stop) { ... } 在IRP_MN_STOP_DEVICE或IRP_MN_REMOVE_DEVICE时把stop设成true,退出来就shut这个线程就可以了 |
|
地板#
发布于:2003-10-09 16:12
我想是不是应该把KeWaitForSingleObject(&pdx->evKill, Executive, KernelMode, FALSE, NULL)这条语句加到while循环中,如果事件没被触发就继续采集数据,否则break退出循环。
|
|
地下室#
发布于:2003-10-09 16:13
你后面的等待和shut线程的语句能执行到?你的死循环退不出来的嘛!把死循环改了三,可以设个标志,比如:
bool stop = false; while(!stop) { ... } 在IRP_MN_STOP_DEVICE或IRP_MN_REMOVE_DEVICE时把stop设成true,退出来就shut这个线程就可以了 我试了。也像你说的改了,但就在PsTerminateSystemThread(STATUS_SUCCESS); 这里它就好像没执行。 typedef struct _DEVICE_EXTENSION { ... KEVENT evKill; PKTHREAD thread; }; NTSTATUS StartThread(PDEVICE_EXTENSION pdx) { NTSTATUS status; HANDLE hthread; isexit=false; KeInitializeEvent(&pdx->evKill, NotificationEvent, FALSE); status = PsCreateSystemThread(&hthread, THREAD_ALL_ACCESS, NULL, NULL, NULL, (PKSTART_ROUTINE) ThreadProc, pdx); if (!NT_SUCCESS(status)) return status; ObReferenceObjectByHandle(hthread, THREAD_ALL_ACCESS, NULL, KernelMode, (PVOID*) &pdx->thread, NULL); ZwClose(hthread); return STATUS_SUCCESS; } VOID StopThread(PDEVICE_EXTENSION pdx) { isexit=true; KeSetEvent( &pdx->evKill, 0, FALSE); KeWaitForSingleObject(pdx->thread, Executive, KernelMode, FALSE, NULL); ObDereferenceObject(pdx->thread); } VOID ThreadProc(PDEVICE_EXTENSION pdx) { while(!isexit) { //采集数据 } KeWaitForSingleObject(&pdx->evKill, Executive, KernelMode, FALSE, NULL);//这里我用的对不对呢。 PsTerminateSystemThread(STATUS_SUCCESS); } |
|
5楼#
发布于:2003-10-09 19:30
while(!isexit)
{ //采集数据 } 这句把时间抢完了。 while(...) { ... sleep(100); // 示例而已,不是这个函数,也不是这个时间 } |
|
6楼#
发布于:2003-10-09 21:16
while(!isexit) 里面加sleep不是很明白,能否再提示一下。 |
|
7楼#
发布于:2003-10-09 21:27
你的while把cpu时间占了,别的线程没机会run
加个sleep的作用是让你的线程放弃对cpu的占用。 在内核不是sleep函数,应该是KeDelayExecutionThread吧。 |
|
8楼#
发布于:2003-10-10 08:11
感谢,给分
|
|
论坛版主
![]() |
9楼#
发布于:2003-10-10 14:30
不应该是时间占完了吧,它自己调度,时间片完了不会自己切换?循环应该没问题。
你试着确定到底循环退出来没有,可以在循环后面加打印语句,如果循环退出来了还关不掉线程那才是你说的后面的问题,但是你说的psterminatesystemthread有问题不太可能,看看wait那个对不对。 问题不大,胜利不远了,祝兄弟成功。 |
|
10楼#
发布于:2003-10-10 15:04
我现在可以了。但我在psterminatesystemthread函数后面加了打印语句,没有执行是什么呢。
VOID ThreadProc(PDEVICE_EXTENSION pdx) { while(!isexit) { //采集数据 } KeWaitForSingleObject(&pdx->evKill, Executive, KernelMode, FALSE, NULL);// PsTerminateSystemThread(STATUS_SUCCESS); KPrint(\"Thread stop“)这句没有打印出来? } 不在郁闷中成长,就在郁闷中毁灭! |
|