lioniamhero
驱动小牛
驱动小牛
  • 注册日期2003-05-31
  • 最后登录2005-10-27
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1740回复:10

请教系统线程无法退出的问题

楼主#
更多 发布于:2003-10-09 11:00
请教系统线程无法退出的问题
  我用的是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);好像不执行,如何知道系统线程已经结束了呢。
qinxg
驱动小牛
驱动小牛
  • 注册日期2002-11-15
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分37分
  • 威望27点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-10-09 11:49
是不是
while(TRUE)
{
//采集数据
}
没有退出??可以在PsTerminateSystemThread加个打印语句看看
wxl_50685330
论坛版主
论坛版主
  • 注册日期2002-11-19
  • 最后登录2018-09-25
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望521点
  • 贡献值0点
  • 好评度419点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-10-09 16:06
:)你后面的等待和shut线程的语句能执行到?你的死循环退不出来的嘛!把死循环改了三,可以设个标志,比如:
 bool stop = false;
 
  while(!stop)
 { ... }

在IRP_MN_STOP_DEVICE或IRP_MN_REMOVE_DEVICE时把stop设成true,退出来就shut这个线程就可以了
根据地的兄弟们,团结就是力量
ysr
ysr
驱动牛犊
驱动牛犊
  • 注册日期2001-05-11
  • 最后登录2015-01-29
  • 粉丝0
  • 关注0
  • 积分79分
  • 威望48点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-10-09 16:12
我想是不是应该把KeWaitForSingleObject(&pdx->evKill, Executive, KernelMode, FALSE, NULL)这条语句加到while循环中,如果事件没被触发就继续采集数据,否则break退出循环。
lioniamhero
驱动小牛
驱动小牛
  • 注册日期2003-05-31
  • 最后登录2005-10-27
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于: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);
}
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
5楼#
发布于:2003-10-09 19:30
while(!isexit)
{
//采集数据
}

这句把时间抢完了。

while(...)

...
sleep(100); // 示例而已,不是这个函数,也不是这个时间
lioniamhero
驱动小牛
驱动小牛
  • 注册日期2003-05-31
  • 最后登录2005-10-27
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2003-10-09 21:16
while(!isexit)
{
//采集数据
}

这句把时间抢完了。

while(...)

...
sleep(100); // 示例而已,不是这个函数,也不是这个时间

里面加sleep不是很明白,能否再提示一下。
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
7楼#
发布于:2003-10-09 21:27
你的while把cpu时间占了,别的线程没机会run
加个sleep的作用是让你的线程放弃对cpu的占用。
在内核不是sleep函数,应该是KeDelayExecutionThread吧。
lioniamhero
驱动小牛
驱动小牛
  • 注册日期2003-05-31
  • 最后登录2005-10-27
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2003-10-10 08:11
感谢,给分
wxl_50685330
论坛版主
论坛版主
  • 注册日期2002-11-19
  • 最后登录2018-09-25
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望521点
  • 贡献值0点
  • 好评度419点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2003-10-10 14:30
不应该是时间占完了吧,它自己调度,时间片完了不会自己切换?循环应该没问题。

你试着确定到底循环退出来没有,可以在循环后面加打印语句,如果循环退出来了还关不掉线程那才是你说的后面的问题,但是你说的psterminatesystemthread有问题不太可能,看看wait那个对不对。
问题不大,胜利不远了,祝兄弟成功。
根据地的兄弟们,团结就是力量
lioniamhero
驱动小牛
驱动小牛
  • 注册日期2003-05-31
  • 最后登录2005-10-27
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
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“)这句没有打印出来?

}
不在郁闷中成长,就在郁闷中毁灭!
游客

返回顶部