随笔 - 60, 文章 - 0, 评论 - 197, 引用 - 0
数据加载中……

Win32 - 如何控制你的线程


一、如何安全的结束你的线程
   在你的线程中设立一个标志,利用其值要求线程结束自己. 我们不是要写一个 busy loop 来检验标志值,我们使用一个手动设置的 event 对象。Wroker 线程可以检查 event 对象的状态或是等待它,视情况而定。

   主线程代码:
   --------------------------------------
   HANDLE hThreads[2];
   DWORD dwThreadID;
   DWORD dwExitCode = 0;

   hRequestExitEvent = CreateEvent(
                   NULL, /* Detault security */
                   TRUE, /* Manual reset */
                   FALSE, /* Non-active state */
                   NULL); /* Event name */

   for (int i = 0; i < 2; ++i)
       hThreads[i] = CreateThread(
                  NULL, /* Default security */
                  0,     /* Default stack size */
                  ThreadFunc, /* Thread function address */
                  (LPVOID)i,  /* Thread parameter */
                  0,          /* Start when creating */
                  &dwThreadID);


    Sleep(1000);
    SetEvent(hRequestExitEvent);
    WaitForMultipleObjects(2, hThreads, TRUE, INFINITE);

    for (i = 0; i < 2; ++i)
        CloseHandle(hThreads[i]);


   线程代码:
   --------------------------------------
   for (i = 0; i < 1000000; ++i)
   {
       // do something

       if (WaitForSingleObject(hRequestExitEvent, 0) != WAIT_TIMEOUT)
       {
       printf("Received request to terminate\n");
       return (DWORD) -1;
       }
    }


二、调整线程优先权

   BOOL SetThreadPriority(HANDLE hThread, int nPriority);

   hThread - 代表线程
   nPriority - 优先权层级数

   TRUE - 成功; FALSE - 失败


   可用下面函数获得线程优先权层级数:
   int GetThreadPriority(HANDLE hThread);


三、创建线程时指定优先权

   HANDLE hThread;
   DWORD thrdId;

   hThread = CreateThread(NULL,
                          0,
                          ThreadFunc,
                          0,
                          CREATE_SUSPEND,
                          &thrdId)
   SetThreadPriority(thrdId, THREAD_PRIORITY_IDLE);


   一旦线程设置妥当,可调用下面函数执行:

   DWORD ResumeThread(HANDLE hThread);

   该函数失败时返回 0xFFFFFFFF


posted on 2009-11-27 18:17 Normandy 阅读(2304) 评论(10)  编辑 收藏 引用 所属分类: Programming

评论

# re: Win32 - 如何控制你的线程  回复  更多评论   

--------------------------------------
for (i = 0; i < 1000000; ++i)
{
// do something

if (WaitForSingleObject(hRequestExitEvent, 0) != WAIT_TIMEOUT)
{
printf("Received request to terminate\n");
return (DWORD) -1;
}
}
如此跟设置一个全局量退出标志没什么两样
2009-11-28 02:14 | wocow3

# re: Win32 - 如何控制你的线程  回复  更多评论   

gone with your dream的意思其实是,带着你的梦想一起消失……
2009-11-28 09:13 | 陈梓瀚(vczh)

# re: Win32 - 如何控制你的线程  回复  更多评论   

标题与内容差十万八千里
2009-11-28 10:05 | zdhsoft

# re: Win32 - 如何控制你的线程  回复  更多评论   

线程里通常是要将这个事件和另一个事件工作(如:队列不为空的事件)一起等待(WaitForMultipleObjects),否则就真不如用一个全局变量了。
2009-11-29 13:47 | 唐新发

# re: Win32 - 如何控制你的线程  回复  更多评论   

@陈梓瀚(vczh)

Good catch, thanks.

Updated the title with "Keep go on with your dream"
2009-11-30 11:14 | Normandy

# re: Win32 - 如何控制你的线程  回复  更多评论   

@wocow3, 唐新发

这里不会引发等待, 因为 WaitForSingleObject 的第二个参数是 0。 另外, 用全局变量作退出标志有一个致命缺点,当两个已上的线程并发读写全局变量的时候, 就会引发竞争,而用 WaitForSingleObject 则是安全的。

2009-11-30 11:21 | Normandy

# re: Win32 - 如何控制你的线程  回复  更多评论   

一个读操作而已。
而且还有cache的存在,没什么竞争。
“WaitForSingleObject 则是安全的”,什么情况下会不安全?
2009-12-04 20:11 | wocow3

# re: Win32 - 如何控制你的线程  回复  更多评论   

"Keep go on with your dream" 两个动词能放一起?
2009-12-05 11:44 | Nick

# re: Win32 - 如何控制你的线程  回复  更多评论   

@wocow3
各线程清理资源并结束自己的时候, 用 WaitForSingleObject() 可保证线程有序的清理资源并退出。

很多情况可引发竞争: 如线程1 欲结束自己, 但仅清理了一半资源,这时发生 context switch, CPU 切换到线程 2, 而线程2 也要清理资源并结束自己,如果清理资源的动作必须保证有序,就会引发竞争。
2009-12-07 15:22 | Normandy

# re: Win32 - 如何控制你的线程  回复  更多评论   

@Nick
见笑了,英语不咋地,多谢兄台提醒 :)

Keep going on with your dream
2009-12-07 15:28 | Normandy

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理