亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

深入淺出Win32多線程程序設計之基本概念

2019-11-17 05:09:09
字體:
來源:轉載
供稿:網友
  引言

  從單進程單線程到多進程多線程是操作系統發展的一種必然趨勢,當年的DOS系統屬于單任務操作系統,最優秀的程序員也只能通過駐留內存的方式實現所謂的"多任務",而如今的Win32操作系統卻可以一邊聽音樂,一邊編程,一邊打印文檔。

  理解多線程及其同步、互斥等通信方式是理解現代操作系統的要害一環,當我們精通了Win32多線程程序設計后,理解和學習其它操作系統的多任務控制也非常輕易。許多程序員從來沒有學習過嵌入式系統領域聞名的操作系統VxWorks,但是立馬就能在上面做開發,大概要歸功于平時在Win32多線程上下的功夫。

  因此,學習Win32多線程不僅對理解Win32本身有重要意義,而且對學習和領會其它操作系統也有觸類旁通的作用。

  進程與線程

  先闡述一下進程和線程的概念和區別,這是一個許多大學老師也講不清楚的問題。

  進程(PRocess)是具有一定獨立功能的程序關于某個數據集合上的一次運行活動,是系統進行資源分配和調度的一個獨立單位。程序只是一組指令的有序集合,它本身沒有任何運行的含義,只是一個靜態實體。而進程則不同,它是程序在某個數據集上的執行,是一個動態實體。它因創建而產生,因調度而運行,因等待資源或事件而被處于等待狀態,因完成任務而被撤消,反映了一個程序在一定的數據集上運行的全部動態過程。

  線程(Thread)是進程的一個實體,是CPU調度和分派的基本單位。線程不能夠獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。

  線程和進程的關系是:線程是屬于進程的,線程運行在進程空間內,同一進程所產生的線程共享同一內存空間,當進程退出時該進程所產生的線程都會被強制退出并清除。線程可與屬于同一進程的其它線程共享進程所擁有的全部資源,但是其本身基本上不擁有系統資源,只擁有一點在運行中必不可少的信息(如程序計數器、一組寄存器和棧)。

  根據進程與線程的設置,操作系統大致分為如下類型:

 ?。?)單進程、單線程,MS-DOS大致是這種操作系統;

 ?。?)多進程、單線程,多數UNIX(及類UNIX的linux)是這種操作系統;

  (3)多進程、多線程,Win32(Windows NT/2000/XP等)、Solaris 2.x和OS/2都是這種操作系統;

 ?。?)單進程、多線程,VxWorks是這種操作系統。

  在操作系統中引入線程帶來的主要好處是:

 ?。?)在進程內創建、終止線程比創建、終止進程要快;

  (2)同一進程內的線程間切換比進程間的切換要快,尤其是用戶級線程間的切換。另外,線程的出現還因為以下幾個原因:

  (1)并發程序的并發執行,在多處理環境下更為有效。一個并發程序可以建立一個進程,而這個并發程序中的若干并發程序段就可以分別建立若干線程,使這些線程在不同的處理機上執行。

  (2)每個進程具有獨立的地址空間,而該進程內的所有線程共享該地址空間。這樣可以解決父子進程模型中,子進程必須復制父進程地址空間的問題。

 ?。?)線程對解決客戶/服務器模型非常有效。

  Win32進程

  1、進程間通信(ipC)

  Win32進程間通信的方式主要有:

 ?。?)剪貼板(Clip Board);

 ?。?)動態數據交換(Dynamic Data Exchange);

 ?。?)部件對象模型(Component Object Model);

 ?。?)文件映射(File Mapping);

  (5)郵件槽(Mail Slots);

 ?。?)管道(Pipes);

 ?。?)Win32套接字(Socket);

 ?。?)遠程過程調用(Remote Procedure Call);

 ?。?)WM_COPYDATA消息(WM_COPYDATA Message)。

  2、獲取進程信息

  在WIN32中,可使用在PSAPI .DLL中提供的Process status Helper函數幫助我們獲取進程信息。

 ?。?)EnumProcesses()函數可以獲取進程的ID,其原型為:

BOOL EnumProcesses(DWord * lpidProcess, DWORD cb, DWORD*cbNeeded);
  參數lpidProcess:一個足夠大的DWORD類型的數組,用于存放進程的ID值;

  參數cb:存放進程ID值的數組的最大長度,是一個DWORD類型的數據;

  參數cbNeeded:指向一個DWORD類型數據的指針,用于返回進程的數目;

  函數返回值:假如調用成功,返回TRUE,同時將所有進程的ID值存放在lpidProcess參數所指向的數組中,進程個數存放在cbNeeded參數所指向的變量中;假如調用失敗,返回FALSE。

 ?。?)GetModuleFileNameExA()函數可以實現通過進程句柄獲取進程文件名,其原型為:

DWORD GetModuleFileNameExA(HANDLE hProcess, HMODULE hModule,LPTSTR lpstrFileName, DWORD nsize);
  參數hProcess:接受進程句柄的參數,是HANDLE類型的變量;

  參數hModule:指針型參數,在本文的程序中取值為NULL;

  參數lpstrFileName:LPTSTR類型的指針,用于接受主調函數傳遞來的用于存放進程名的字符數組指針;

  參數nsize:lpstrFileName所指數組的長度;

  函數返回值:假如調用成功,返回一個大于0的DWORD類型的數據,同時將hProcess所對應的進程名存放在lpstrFileName參數所指向的數組中;加果調用失敗,則返回0。

  通過下列代碼就可以遍歷系統中的進程,獲得進程列表:

//獲取當前進程總數
EnumProcesses(process_ids, sizeof(process_ids), &num_processes);
//遍歷進程
for (int i = 0; i < num_processes; i++)
{
 //根據進程ID獲取句柄
 process[i] = OpenProcess(PROCESS_QUERY_INFORMATION PROCESS_VM_READ, 0,
 process_ids[i]);
 //通過句柄獲取進程文件名
 if (GetModuleFileNameExA(process[i], NULL, File_name, sizeof(fileName)))
  cout << fileName << endl;
}

  Win32線程

  WIN32靠線程的優先級(達到搶占式多任務的目的)及分配給線程的CPU時間來調度線程。WIN32本身的許多應用程序也利用了多線程的特性,如任務治理器等。

  本質而言,一個處理器同一時刻只能執行一個線程("微觀串行")。WIN32多任務機制使得CPU似乎在同時處理多個任務一樣,實現了"宏觀并行"。其多線程調度的機制為:

 ?。?)運行一個線程,直到被中斷或線程必須等待到某個資源可用;

  (2)保存當前執行線程的描述表(上下文);

 ?。?)裝入下一執行線程的描述表(上下文);

 ?。?)若存在等待被執行的線程,則重復上述過程。

  WIN32下的線程可能具有不同的優先級,優先級的范圍為0~31,共32級,其中31表示最高優先級,優先級0為系統保留。它們可以分成兩類,即實時優先級和可變優先級:

  (1)實時優先級從16到31,是實時程序所用的高優先級線程,如許多監控類應用程序;

 ?。?)可變優先級從1到15,絕大多數程序的優先級都在這個范圍內。。WIN32調度器為了優化系統響應時間,在它們執行過程中可動態調整它們的優先級。

  多線程確實給應用開發帶來了許多好處,但并非任何情況下都要使用多線程,一定要根據應用程序的具體情況來綜合考慮。一般來說,在以下情況下可以考慮使用多線程:

 ?。?)應用程序中的各任務相對獨立;

 ?。?)某些任務耗時較多;

 ?。?)各任務需要有不同的優先級。

  另外,對于一些實時系統應用,應考慮多線程。

  Win32核心對象

  WIN32核心對象包括進程、線程、文件、事件、信號量、互斥體和管道,核心對象可能有不只一個擁有者,甚至可以跨進程。有一組WIN32 API與核心對象息息相關:

  (1)WaitForSingleObject,用于等待對象的"激活",其函數原型為:

DWORD WaitForSingleObject(
 HANDLE hHandle, // 等待對象的句柄
 DWORD dwMilliseconds // 等待毫秒數,INFINITE表示無限等待
);

  可以作為WaitForSingleObject第一個參數的對象包括:Change notification、Console input、Event、Job、Memory resource notification、Mutex、Process、Semaphore、Thread和Waitable timer。

  假如等待的對象不可用,那么線程就會掛起,直到對象可用線程才會被喚醒。對不同的對象,WaitForSingleObject表現為不同的含義。例如,使用WaitForSingleObject(hThread,…)可以判定一個線程是否結束;使用WaitForSingleObject(hMutex,…)可以判定是否能夠進入臨界區;而WaitForSingleObject (hProcess,… )則表現為等待一個進程的結束。

  與WaitForSingleObject對應還有一個WaitForMultipleObjects函數,可以用于等待多個對象,其原型為:

DWORD WaitForMultipleObjects(DWORD nCount,const HANDLE* pHandles,BOOL bWaitAll,DWORD dwMilliseconds);
  (2)CloseHandle,用于關閉對象,其函數原型為:

BOOL CloseHandle(HANDLE hObject);
  假如函數執行成功,則返回TRUE;否則返回FALSE,我們可以通過GetLastError函數進一步可以獲得錯誤原因。

  C運行時庫

  在VC++6.0中,有兩種多線程編程方法:一是使用C運行時庫及WIN32 API函數,另一種方法是使用MFC,MFC對多線程開發有強大的支持。
標準C運行時庫是1970年問世的,當時還沒有多線程的概念。因此,C運行時庫早期的設計者們不可能考慮到讓其支持多線程應用程序。
Visual C++提供了兩種版本的C運行時庫,-個版本供單線程應用程序調用,另一個版本供多線程應用程序調用。多線程運行時庫與單線程運行時庫有兩個重大差別:

 ?。?)類似errno的全局變量,每個線程單獨設置一個;

  這樣從每個線程中可以獲取正確的錯誤信息。

 ?。?)多線程庫中的數據結構以同步機制加以保護。

  這樣可以避免訪問時候的沖突。


  Visual C++提供的多線程運行時庫又分為靜態鏈接庫和動態鏈接庫兩類,而每一類運行時庫又可再分為debug版和release版,因此Visual C++共提供了6個運行時庫。如下表:

C運行時庫庫文件Single thread(static link)libc.libDebug single thread(static link)Libcd.libMultiThread(static link)libcmt.libDebug multiThread(static link)libcmtd.libMultiThread(dynamic link)msvert.libDebug multiThread(dynamic link)msvertd.lib
  假如不使用VC多線程C運行時庫來生成多線程程序,必須執行下列操作:

 ?。?)使用標準 C 庫(基于單線程)并且只答應可重入函數集進行庫調用;

 ?。?)使用 Win32 API 線程治理函數,如 CreateThread;

  (3)通過使用 Win32 服務(如信號量和 EnterCriticalSection 及 LeaveCriticalSection 函數),為不可重入的函數提供自己的同步。

  假如使用標準 C 庫而調用VC運行時庫函數,則在程序的link階段會提示如下錯誤:

error LNK2001: unresolved external symbol __endthreadex
error LNK2001: unresolved external symbol __beginthreadex


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
成人一区二区电影| 精品国产999| 国产精品久久国产精品99gif| 91亚洲午夜在线| 亚洲国语精品自产拍在线观看| 欧美性生交xxxxxdddd| 精品一区二区三区四区| 久久久久久久久爱| 欧美一级大片在线免费观看| 一区二区三区亚洲| 日本中文字幕久久看| 欧美性猛交xxxx免费看漫画| 欧美大片网站在线观看| 欧美多人乱p欧美4p久久| 日韩av大片在线| 欧美日韩国产一中文字不卡| 亚洲自拍偷拍色片视频| 日韩一级裸体免费视频| 欧美成人精品在线| 成人在线小视频| 欧美精品激情在线观看| 精品国产美女在线| 一区二区三区四区在线观看视频| 日韩大陆欧美高清视频区| 91精品久久久久久久久中文字幕| 国产69久久精品成人| 在线看日韩欧美| 久久久久久久久91| 两个人的视频www国产精品| 亚洲欧美成人在线| 精品一区二区三区四区在线| 日韩在线欧美在线国产在线| 精品无人区太爽高潮在线播放| 久操成人在线视频| 国产精品com| 91九色在线视频| 国产v综合ⅴ日韩v欧美大片| 欧美成人第一页| 国产裸体写真av一区二区| 欧美一级片久久久久久久| 日产精品99久久久久久| 亚洲视频国产视频| 中文字幕在线看视频国产欧美在线看完整| 国产美女直播视频一区| 亚洲欧美日韩爽爽影院| 国产成人一区二区三区| 欧美日韩国产综合新一区| 国产精品视频在线观看| 国产69久久精品成人| 亚洲小视频在线| 韩剧1988免费观看全集| 亚洲国产黄色片| 久久精品国产2020观看福利| 日韩精品在线观看一区二区| 久久精品夜夜夜夜夜久久| 日韩大片免费观看视频播放| 久久精品人人爽| 亚洲自拍小视频| 91九色在线视频| 亚洲香蕉成人av网站在线观看| 久久精品国产2020观看福利| 性色av一区二区三区| 国模gogo一区二区大胆私拍| 国模精品一区二区三区色天香| 日韩美女毛茸茸| 日韩精品亚洲精品| 亚洲一区二区三区sesese| 欧美激情一区二区三区成人| 不卡在线观看电视剧完整版| 亚洲在线免费视频| 久久av资源网站| 在线观看久久av| 亚洲精品网站在线播放gif| 色偷偷888欧美精品久久久| 成人激情视频免费在线| 亚洲第一福利网| 亚洲成在人线av| 精品久久久久久久大神国产| 久久精品欧美视频| 青青精品视频播放| 一本色道久久综合狠狠躁篇怎么玩| 日韩精品免费视频| 久久97精品久久久久久久不卡| 成人黄色av网站| 97免费视频在线播放| 97精品国产97久久久久久春色| 成人黄色大片在线免费观看| 91久久精品日日躁夜夜躁国产| 成人网在线观看| 亚洲免费电影在线观看| 91综合免费在线| 亚洲国产天堂久久国产91| 欧美性videos高清精品| 国产精品毛片a∨一区二区三区|国| 国产精品美女久久久久av超清| 国产精品第七影院| 亚洲欧美在线看| 欧美精品videossex88| 国产精品偷伦免费视频观看的| 亚洲最大成人免费视频| 久久激情视频久久| 欧美一级在线亚洲天堂| 色偷偷噜噜噜亚洲男人| 国产免费观看久久黄| 亚洲综合在线播放| 亚洲视频第一页| 欧美性猛交xxxx乱大交3| 欧美午夜女人视频在线| 91精品国产一区| 国产精品第100页| 成人疯狂猛交xxx| 久久精品国产亚洲7777| 国产成人精品网站| 91精品国产综合久久香蕉最新版| 国产91热爆ts人妖在线| 欧美黄色片免费观看| 一区二区三区视频观看| 亚洲精品久久久久| 亚洲免费视频一区二区| 欧美野外wwwxxx| 亚洲人成电影在线| 在线一区二区日韩| 欧美日韩亚洲国产一区| www.日韩免费| 成人福利在线观看| 国产亚洲在线播放| 国产精品日日做人人爱| 日本久久久久久久久| 国产精品精品视频一区二区三区| 欧美与欧洲交xxxx免费观看| 国产精品自产拍在线观看| 色狠狠av一区二区三区香蕉蜜桃| 久久国产精品久久国产精品| 国产精品久久久久久av下载红粉| 国产在线观看精品一区二区三区| 日韩av网址在线| 日本精品久久久久久久| 日韩在线小视频| 午夜精品一区二区三区在线视| 午夜剧场成人观在线视频免费观看| 国产一区二区三区在线观看视频| 色樱桃影院亚洲精品影院| 亚洲自拍av在线| 亚洲国产91精品在线观看| 国产成人精品免费视频| 在线看日韩欧美| 久久久久久18| 久久久亚洲网站| 欧美自拍视频在线| 欧美麻豆久久久久久中文| 中文字幕亚洲一区二区三区| 国产不卡视频在线| 日韩欧美在线免费观看| 国产一区二区三区在线观看视频| 国产美女直播视频一区| 91久久中文字幕| 97超碰蝌蚪网人人做人人爽| 久久成人在线视频| 国产在线不卡精品| 亚洲欧美日韩在线一区| 高清视频欧美一级| 亚洲国产精品小视频| 日韩在线免费高清视频| 高清视频欧美一级|