• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            5.設(shè)置線程優(yōu)先級

              當(dāng)一個線程被首次創(chuàng)建時,它的優(yōu)先級等同于它所屬進程的優(yōu)先級。在單個進程內(nèi)可以通過調(diào)用SetThreadPriority函數(shù)改變線程的相對優(yōu)先級。一個線程的優(yōu)先級是相對于其所屬進程的優(yōu)先級而言的。

            BOOL SetThreadPriority(HANDLE hThread, int nPriority);

              其中參數(shù)hThread是指向待修改優(yōu)先級線程的句柄,線程與包含它的進程的優(yōu)先級關(guān)系如下:

               線程優(yōu)先級 = 進程類基本優(yōu)先級 + 線程相對優(yōu)先級

              進程類的基本優(yōu)先級包括:

              (1)實時:REALTIME_PRIORITY_CLASS;

              (2)高:HIGH _PRIORITY_CLASS;

              (3)高于正常:ABOVE_NORMAL_PRIORITY_CLASS;

              (4)正常:NORMAL _PRIORITY_CLASS;

              (5)低于正常:BELOW_ NORMAL _PRIORITY_CLASS;

              (6)空閑:IDLE_PRIORITY_CLASS。

              我們從Win32任務(wù)管理器中可以直觀的看到這六個進程類優(yōu)先級,如下圖:


              線程的相對優(yōu)先級包括:

              (1)空閑:THREAD_PRIORITY_IDLE;

              (2)最低線程:THREAD_PRIORITY_LOWEST;

              (3)低于正常線程:THREAD_PRIORITY_BELOW_NORMAL;

              (4)正常線程:THREAD_PRIORITY_ NORMAL (缺省);

              (5)高于正常線程:THREAD_PRIORITY_ABOVE_NORMAL;

              (6)最高線程:THREAD_PRIORITY_HIGHEST;

              (7)關(guān)鍵時間:THREAD_PRIOTITY_CRITICAL。

              下圖給出了進程優(yōu)先級和線程相對優(yōu)先級的映射關(guān)系:


              例如:

            HANDLE hCurrentThread = GetCurrentThread();
            //獲得該線程句柄
            SetThreadPriority(hCurrentThread, THREAD_PRIORITY_LOWEST);

              6.睡眠

            VOID Sleep(DWORD dwMilliseconds);

              該函數(shù)可使線程暫停自己的運行,直到dwMilliseconds毫秒過去為止。它告訴系統(tǒng),自身不想在某個時間段內(nèi)被調(diào)度。

              7.其它重要API

              獲得線程優(yōu)先級

              一個線程被創(chuàng)建時,就會有一個默認的優(yōu)先級,但是有時要動態(tài)地改變一個線程的優(yōu)先級,有時需獲得一個線程的優(yōu)先級。

            Int GetThreadPriority (HANDLE hThread);

              如果函數(shù)執(zhí)行發(fā)生錯誤,會返回THREAD_PRIORITY_ERROR_RETURN標志。如果函數(shù)成功地執(zhí)行,會返回優(yōu)先級標志。

              獲得線程退出碼

            BOOL WINAPI GetExitCodeThread(
             HANDLE hThread,
             LPDWORD lpExitCode
            );

              如果執(zhí)行成功,GetExitCodeThread返回TRUE,退出碼被lpExitCode指向內(nèi)存記錄;否則返回FALSE,我們可通過GetLastError()獲知錯誤原因。如果線程尚未結(jié)束,lpExitCode帶回來的將是STILL_ALIVE。

            獲得/設(shè)置線程上下文
            BOOL WINAPI GetThreadContext(
             HANDLE hThread,
             LPCONTEXT lpContext
            );
            BOOL WINAPI SetThreadContext(
             HANDLE hThread,
             CONST CONTEXT *lpContext
            );

              由于GetThreadContext和SetThreadContext可以操作CPU內(nèi)部的寄存器,因此在一些高級技巧的編程中有一定應(yīng)用。譬如,調(diào)試器可利用GetThreadContext掛起被調(diào)試線程獲取其上下文,并設(shè)置上下文中的標志寄存器中的陷阱標志位,最后通過SetThreadContext使設(shè)置生效來進行單步調(diào)試。

              8.實例

              以下程序使用CreateThread創(chuàng)建兩個線程,在這兩個線程中Sleep一段時間,主線程通過GetExitCodeThread來判斷兩個線程是否結(jié)束運行:

            #define WIN32_LEAN_AND_MEAN
            #include <stdio.h>
            #include <stdlib.h>
            #include <windows.h>
            #include <conio.h>

            DWORD WINAPI ThreadFunc(LPVOID);

            int main()
            {
             HANDLE hThrd1;
             HANDLE hThrd2;
             DWORD exitCode1 = 0;
             DWORD exitCode2 = 0;
             DWORD threadId;

             hThrd1 = CreateThread(NULL, 0, ThreadFunc, (LPVOID)1, 0, &threadId );
             if (hThrd1)
              printf("Thread 1 launched\n");

             hThrd2 = CreateThread(NULL, 0, ThreadFunc, (LPVOID)2, 0, &threadId );
             if (hThrd2)
              printf("Thread 2 launched\n");

             // Keep waiting until both calls to GetExitCodeThread succeed AND
             // neither of them returns STILL_ACTIVE.
             for (;;)
             {
              printf("Press any key to exit..\n");
              getch();

              GetExitCodeThread(hThrd1, &exitCode1);
              GetExitCodeThread(hThrd2, &exitCode2);
              if ( exitCode1 == STILL_ACTIVE )
               puts("Thread 1 is still running!");
              if ( exitCode2 == STILL_ACTIVE )
               puts("Thread 2 is still running!");
              if ( exitCode1 != STILL_ACTIVE && exitCode2 != STILL_ACTIVE )
               break;
             }

             CloseHandle(hThrd1);
             CloseHandle(hThrd2);

             printf("Thread 1 returned %d\n", exitCode1);
             printf("Thread 2 returned %d\n", exitCode2);

             return EXIT_SUCCESS;
            }

            /*
            * Take the startup value, do some simple math on it,
            * and return the calculated value.
            */
            DWORD WINAPI ThreadFunc(LPVOID n)
            {
             Sleep((DWORD)n*1000*2);
             return (DWORD)n * 10;
            }

              通過下面的程序我們可以看出多線程程序運行順序的難以預(yù)料以及WINAPI的CreateThread函數(shù)與C運行時庫的_beginthread的差別:

            #define WIN32_LEAN_AND_MEAN
            #include <stdio.h>
            #include <stdlib.h>
            #include <windows.h>

            DWORD WINAPI ThreadFunc(LPVOID);

            int main()
            {
             HANDLE hThrd;
             DWORD threadId;
             int i;

             for (i = 0; i < 5; i++)
             {
              hThrd = CreateThread(NULL, 0, ThreadFunc, (LPVOID)i, 0, &threadId);
              if (hThrd)
              {
               printf("Thread launched %d\n", i);
               CloseHandle(hThrd);
              }
             }
             // Wait for the threads to complete.
             Sleep(2000);

             return EXIT_SUCCESS;
            }

            DWORD WINAPI ThreadFunc(LPVOID n)
            {
             int i;
             for (i = 0; i < 10; i++)
              printf("%d%d%d%d%d%d%d%d\n", n, n, n, n, n, n, n, n);
             return 0;
            }

              運行的輸出具有很大的隨機性,這里摘取了幾次結(jié)果的一部分(幾乎每一次都不同):


              如果我們使用標準C庫函數(shù)而不是多線程版的運行時庫,則程序可能輸出"3333444444"這樣的結(jié)果,而使用多線程運行時庫后,則可避免這一問題。

              下列程序在主線程中創(chuàng)建一個SecondThread,在SecondThread線程中通過自增對Counter計數(shù)到1000000,主線程一直等待其結(jié)束:

            #include <Win32.h>
            #include <stdio.h>
            #include <process.h>

            unsigned Counter;
            unsigned __stdcall SecondThreadFunc(void *pArguments)
            {
             printf("In second thread...\n");

             while (Counter < 1000000)
              Counter++;

             _endthreadex(0);
             return 0;
            }

            int main()
            {
             HANDLE hThread;
             unsigned threadID;

             printf("Creating second thread...\n");

             // Create the second thread.
             hThread = (HANDLE)_beginthreadex(NULL, 0, &SecondThreadFunc, NULL, 0, &threadID);

             // Wait until second thread terminates
             WaitForSingleObject(hThread, INFINITE);
             printf("Counter should be 1000000; it is-> %d\n", Counter);
             // Destroy the thread object.
             CloseHandle(hThread);
            }
            ?
            Posted on 2006-11-18 14:21 艾凡赫 閱讀(1075) 評論(0)  編輯 收藏 引用 所屬分類: 多線程
            国内精品久久久久久久久电影网| 噜噜噜色噜噜噜久久| 日韩精品久久久久久久电影| 国产亚洲色婷婷久久99精品91| 国产精品久久久久久久久鸭| 91久久婷婷国产综合精品青草| 精品国产VA久久久久久久冰| 久久精品国产亚洲av麻豆小说 | 精品一久久香蕉国产线看播放| 精品久久人妻av中文字幕| 久久青青草原精品国产| 久久国产精品-国产精品| 久久国产视频网| 久久婷婷人人澡人人爽人人爱| 无码精品久久久天天影视| 久久99国产精品二区不卡| 久久毛片免费看一区二区三区| 久久久久久久久66精品片| 亚洲精品tv久久久久久久久| 国产精品久久久久久吹潮| 国产精品无码久久四虎| 色天使久久综合网天天| 久久中文字幕一区二区| 久久国产精品偷99| 欧美喷潮久久久XXXXx| 色综合合久久天天综合绕视看| 亚洲欧洲精品成人久久曰影片 | 国产精品99久久久久久猫咪| 亚洲国产成人久久笫一页| 久久成人国产精品| 久久国产精品免费一区| 久久AV高潮AV无码AV| 精品国产一区二区三区久久蜜臀| 性做久久久久久免费观看| 91精品国产91久久综合| 国产精品久久久久蜜芽| 一本大道加勒比久久综合| 亚洲国产综合久久天堂| 国产精品久久久久久福利漫画 | 精品久久久久中文字| 国产V亚洲V天堂无码久久久|