版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、Windows系統(tǒng)編程實用教程授課教師:職務:Windows系統(tǒng)編程實用教程授課教師:第7章 進程編程課程描述大多數(shù)應用程序都以進程的形式運行,有時還需要在應用程序里運行或結束其他進程。本章將介紹Windows進程編程的方法。第7章 進程編程課程描述本章知識點7.1 進程編程基礎7.2 基本進程編程7.3 進程間通信本章知識點7.1 進程編程基礎7.1 進程編程基礎7.1.1 什么是進程7.1.2 進程的狀態(tài)7.1 進程編程基礎7.1.1 什么是進程7.1.1 什么是進程進程是正在運行的程序的實例。每個運行的Visual C+項目都對應一個進程,每個進程至少包含一個線程,它從main()函數(shù)開
2、始執(zhí)行,直到執(zhí)行return語句返回,主線程結束,該進程也被從內(nèi)存中卸載。進程由如下幾個部分組成。與程序相關聯(lián)的可執(zhí)行代碼的映像;內(nèi)存空間(通常是虛擬內(nèi)存中的一些區(qū)域),其中保存可執(zhí)行代碼、進程的特定數(shù)據(jù)、用于記錄活動例程和其他事件的調(diào)用棧、用于保存實時產(chǎn)生的中間計算結果的堆(heap)。分配給進程的資源的操作系統(tǒng)描述符(比如文件句柄)以及其他數(shù)據(jù)資源。安全屬性,比如進程的所有者和權限。處理器的狀態(tài),比如寄存器的內(nèi)容、物理內(nèi)存地址等。7.1.1 什么是進程進程是正在運行的程序的實例。每個運行7.1.2 進程的狀態(tài) 7.1.2 進程的狀態(tài) 7.2 基本進程編程7.2.1 創(chuàng)建進程7.2.2 枚舉
3、系統(tǒng)進程7.2.3 終止進程7.2 基本進程編程7.2.1 創(chuàng)建進程7.2.1 創(chuàng)建進程在應用程序中可以調(diào)用CreateProcess()函數(shù)創(chuàng)建一個新進程、運行其他程序,函數(shù)原型如下:BOOL WINAPI CreateProcess( _in LPCTSTR lpApplicationName, _in_out LPTSTR lpCommandLine, _in LPSECURITY_ATTRIBUTES lpProcessAttributes, _in LPSECURITY_ATTRIBUTES lpThreadAttributes, _in BOOL bInheritHandles,
4、_in DWORD dwCreationFlags, _in LPVOID lpEnvironment, _in LPCTSTR lpCurrentDirectory, _in LPSTARTUPINFO lpStartupInfo, _out LPPROCESS_INFORMATION lpProcessInformation);7.2.1 創(chuàng)建進程在應用程序中可以調(diào)用CreatePro參數(shù)說明lpApplicationName,要執(zhí)行的應用程序名,可以包括結對路徑和文件名,通??梢詾镹ULL。lpCommandLine,要執(zhí)行的命令行。lpProcessAttributes,新進程的安全描
5、述符。lpThreadAttributes,指定主線程的安全描述符。如果為NULL,則使用默認的安全描述符。bInheritHandles,指示新進程是否從調(diào)用進程處繼承句柄。dwCreationFlags,指定附加的、用來控制優(yōu)先類和進程創(chuàng)建的標志。lpEnvironment,指向新進程的環(huán)境塊。如果為NULL,則使用調(diào)用CreateProcess()函數(shù)的進程的環(huán)境。參數(shù)說明lpApplicationName,要執(zhí)行的應用程序【例7.1】調(diào)用CreateProcess()函數(shù)運行Windows計算器程序,并顯示新進程的ID號,及其主線程的Id號,代碼如下:#include stdafx.h
6、#include int _tmain(int argc, _TCHAR* argv)char szCommandLine=calc.exe;STARTUPINFO si = sizeof(si);PROCESS_INFORMATION pi;si.dwFlags = STARTF_USESHOWWINDOW; / 指定wShowWindow成員有效si.wShowWindow = TRUE; / 顯示新建進程的主窗口【例7.1】調(diào)用CreateProcess()函數(shù)運行Win接上BOOL bRet = CreateProcess (NULL, / 不在此指定可執(zhí)行文件的文件名szComman
7、dLine, / 命令行參數(shù)NULL,/ 默認進程安全性NULL,/ 默認進程安全性FALSE,/ 指定當前進程內(nèi)句柄不可以被子進程繼承CREATE_NEW_CONSOLE, / 為新進程創(chuàng)建一個新的控制臺窗口NULL,/ 使用本進程的環(huán)境變量NULL,/ 使用本進程的驅動器和目錄&si,&pi) ; if(bRet)/ 關掉不使用的句柄CloseHandle(pi.hThread);CloseHandle(pi.hProcess);printf(新進程的ID號:%dn,pi.dwProcessId);printf(新進程的主線程ID號:%dn,pi.dwThreadId); system(p
8、ause);return 0;接上BOOL bRet = CreateProcess (N【例7.1】的運行結果【例7.1】的運行結果ShellExecute()函數(shù)HINSTANCEShellExecute(HWNDhwnd,/ 指定顯示用戶界面和錯誤信息的窗口句柄LPCTSTRlpOperation,/ 對指定文件要執(zhí)行的操作LPCTSTRlpFile,/ 要執(zhí)行操作的文件或對象LPCTSTRlpParameters,/ 指定傳送給應用程序的參數(shù)LPCTSTRlpDirectory,/ 指定執(zhí)行操作的工作目錄INTnShowCmd/ 指定應用程序如何顯示。SW_HIDE表示隱藏窗口,SW_
9、MAXIMIZE表示最大化窗口,SW_MINIMIZE表示最小化窗口,SW_SHOW表示在當前位置上以當前大小顯示窗口,等等);ShellExecute()函數(shù)HINSTANCEShelpOperation參數(shù)的取值取 值說 明edit打開一個文檔文件進行編輯。如果參數(shù)lpFile指定的不是一個文檔文件,則操作失敗explore打開資源管理器查看指定文件所在的目錄find從參數(shù)lpDirectory指定的目錄開始搜索open打開指定的對象print打印指定的對象。如果參數(shù)lpFile指定的不是一個文檔文件,則操作失敗NULL執(zhí)行默認的操作,通常執(zhí)行open操作pOperation參數(shù)的取值取
10、值說 明edit【例7.2】【例7.2】調(diào)用ShellExecute ()函數(shù)訪問google網(wǎng)站,代碼如下:#include stdafx.h#include windows.h”int _tmain(int argc, _TCHAR* argv)ShellExecute(NULL, open, , , , SW_SHOW);return 0;【例7.2】【例7.2】調(diào)用ShellExecute ()函7.2.2 枚舉系統(tǒng)進程1使用EnumProcesses()函數(shù)2使用進程快照7.2.2 枚舉系統(tǒng)進程1使用EnumProcesses1使用EnumProcesses()函數(shù)BOOL WINA
11、PI EnumProcesses( _out DWORD* pProcessIds,/ 用于接收進程標示符列表的數(shù)組 _in DWORD cb,/ 數(shù)組pProcessIds的大小,單位是字節(jié) _out DWORD* pBytesReturned/ 數(shù)組pProcessIds中返回數(shù)據(jù)的大小,單位是字節(jié));如果函數(shù)執(zhí)行成功,則返回一個非0值;否則返回0。1使用EnumProcesses()函數(shù)BOOL WINA【例7.3】調(diào)用EnumProcess ()函數(shù)枚舉當前Windows運行進程的標示符(PID),代碼如下:#include stdafx.h#include #include #pra
12、gma comment(lib, Psapi.lib)int _tmain(int argc, _TCHAR* argv) / 用于接收返回的進程ID信息的數(shù)組 DWORD dwProcs1024*2; DWORD dwNeeded;/返回進程數(shù)組的大小 /枚舉所有進程ID?!纠?.3】調(diào)用EnumProcess ()函數(shù)枚舉當前Wi接上 if (!EnumProcesses( dwProcs, sizeof(dwProcs), &dwNeeded) /輸出出錯信息。 printf(EnumProcesses failed (%d).n, GetLastError(); else DWORD
13、dwProcCount = dwNeeded / sizeof(DWORD);for(int i=0; idwProcCount; i+)printf(PID: %dn,dwProcsi); system(pause);return 0;接上 if (!EnumProcesses( dwProc【例7.3】的運行結果【例7.3】的運行結果2使用進程快照HANDLE WINAPI CreateToolhelp32Snapshot( DWORD dwFlags, /指定快照中包含的對象 DWORD th32ProcessID / 指定獲取進程快照的PID。如果為0,則獲取當前系統(tǒng)進程列表);如果函
14、數(shù)執(zhí)行成功,則返回進程快照的句柄;否則返回INVALID_HANDLE_VALUE。2使用進程快照HANDLE WINAPI CreateToProcess32First()函數(shù)調(diào)用Process32First()函數(shù)可以從進程快照中獲取第1個進程的信息,函數(shù)原型如下:BOOL WINAPI Process32First( HANDLE hSnapshot, / 之前調(diào)用createtoolhelp32napshot()函數(shù)得到的進程快照句柄 LPPROCESSENTRY32 lppe / 包含進程信息的結構體);Process32First()函數(shù)調(diào)用Process32F結構體LPPROCE
15、SSENTRY32LANA_ENUM結構體中包含當前邏輯網(wǎng)絡適配器的數(shù)量。當一個物理網(wǎng)絡適配器綁定到一個網(wǎng)絡協(xié)議時,就對應一個邏輯網(wǎng)絡適配器。執(zhí)行NCB命令NCBENUM可以向LANA_ENUM結構體中填充邏輯網(wǎng)絡適配器的個數(shù)和邏輯網(wǎng)絡適配器編號,此時NCB結構體中的ncb_buffer成員變量指向LANA_ENUM結構體。LANA_ENUM結構體的定義代碼如下:typedef struct _LANA_ENUM UCHAR length; UCHAR lanaMAX_LANA;LANA_ENUM, *PLANA_ENUM;參數(shù)說明如下:length,系統(tǒng)中包含的邏輯網(wǎng)絡適配器數(shù)量。lanaM
16、AX_LANA,系統(tǒng)中包含的邏輯網(wǎng)絡適配器編號數(shù)組。結構體LPPROCESSENTRY32LANA_ENUM結構Process32Next()函數(shù)調(diào)用Process32Next()函數(shù)可以從進程快照中獲取下一個進程的信息,函數(shù)原型如下:BOOL WINAPI Process32Next( HANDLE hSnapshot, 、/ 之前調(diào)用createtoolhelp32napshot()函數(shù)得到的進程快照句柄 LPPROCESSENTRY32 lppe / 包含進程信息的結構體);如果函數(shù)執(zhí)行成功,則返回TRUE;否則返回FALSE。Process32Next()函數(shù)調(diào)用Process32Ne
17、【例7.4】利用進程快照枚舉當前Windows運行進程的信息,代碼如下:#include stdafx.h#include windows.h#include tlhelp32.hint _tmain(int argc, _TCHAR* argv)PROCESSENTRY32 pe;/設置結構體pe的大小pe.dwSize = sizeof(pe);/獲取系統(tǒng)內(nèi)進程的快照HANDLE hProcessSnap = :CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);if (hProcessSnap = INVALID_HANDLE_VALUE) pr
18、intf(CreateToolhelp32Snapshot error.n);return -1;【例7.4】利用進程快照枚舉當前Windows運行進程的信息接上/遍歷進程快照,顯示每個進程的信息BOOL bMore = :Process32First(hProcessSnap,&pe);while (bMore) printf(=n);printf(Process Name:%sn,pe.szExeFile);printf(PID:%un,pe.th32ProcessID);printf(Number of Thread:%un,tThreads);printf(=n);bMore = :P
19、rocess32Next(hProcessSnap,&pe);/釋放snapshot對象:CloseHandle(hProcessSnap);system(pause);return 0;接上/遍歷進程快照,顯示每個進程的信息4ASTAT結構體ASTAT結構體用于描述網(wǎng)絡適配器的狀態(tài)和名字信息,定義代碼如下:typedef struct ADAPTER_STATUS adapt; NAME_BUFFER NameBuff30; ASTAT;參數(shù)adapt表示網(wǎng)絡適配器的狀態(tài)信息,參數(shù)NameBuff表示網(wǎng)絡適配器中保存的本地網(wǎng)絡名字信息。4ASTAT結構體ASTAT結構體用于描述網(wǎng)絡適配器的狀
20、態(tài)【例7.4】的運行結果【例7.4】的運行結果7.2.3 終止進程進程從主函數(shù)的第一行代碼開始執(zhí)行,直到主函數(shù)結束時終止;也可以強制結束一個進程。當進程被終止時,系統(tǒng)會進行下面的操作:進程中的所有線程都被標記為“終止”狀態(tài);分配給進程的所有資源都會被釋放掉;所有與該進程相關的內(nèi)核對象都會被關閉;從內(nèi)存中移除該進程的代碼;系統(tǒng)設置進程的退出代碼;將該進程對象設置為“受信”(Sigaled)狀態(tài)。7.2.3 終止進程進程從主函數(shù)的第一行代碼開始執(zhí)行,直到GetExitCodeProcess()函數(shù)調(diào)用GetExitCodeProcess()函數(shù)可以獲取進程的終止狀態(tài),函數(shù)原型如下:BOOL WIN
21、API GetExitCodeProcess( _inHANDLE hProcess,/ 進程句柄 _outLPDWORD lpExitCode/ 用于接收進程的終止狀態(tài));如果函數(shù)執(zhí)行成功,則返回TRUE;否則返回FALSE。當進程在運行中時,其終止狀態(tài)為STILL_ACTIVE。當進程被終止時,其終止狀態(tài)變成退出代碼。GetExitCodeProcess()函數(shù)調(diào)用GetExiExitProcess()函數(shù)在進程中調(diào)用ExitProcess()函數(shù)終止其自身中所有的線程,函數(shù)原型如下:VOID WINAPI ExitProcess( _inUINT uExitCode/ 退出代碼);Exi
22、tProcess()函數(shù)在進程中調(diào)用ExitProceTerminateProcess()函數(shù)調(diào)用TerminateProcess()函數(shù)可以終止指定的進程,函數(shù)原型如下:BOOL WINAPI TerminateProcess( _inHANDLE hProcess,/ 要終止的進程句柄 _inUINT uExitCode/退出代碼);TerminateProcess()函數(shù)調(diào)用Terminat7.3 進程間通信7.3.1 通過自定義消息進行通信7.3.2 通過管道進行通信7.3.3 使用互斥體7.3.4 通過共享內(nèi)存進行通信7.3 進程間通信7.3.1 通過自定義消息進行通信7.3.1 通
23、過自定義消息進行通信1定義自定義消息的代碼2發(fā)送消息3消息處理函數(shù)7.3.1 通過自定義消息進行通信1定義自定義消息的代碼1定義自定義消息的代碼為了唯一標識自定義消息,需要為其定義一個消息代碼。自定義的消息代碼都比WM_USER要大,因為0 WM_USER-1是保留給系統(tǒng)消息使用??梢允褂孟旅娴拇a定義一個自定義消息WM_MY_MESSAGE:#define WM_MY_MESSAGE (WM_USER+100)1定義自定義消息的代碼為了唯一標識自定義消息,需要為其定義2發(fā)送消息調(diào)用PostMessage()函數(shù)將消息放置到與創(chuàng)建指定窗口的進程相關聯(lián)的消息隊列中,函數(shù)不需要等待接收方接受和處理
24、消息就直接返回。函數(shù)原型如下:BOOL PostMessage( HWND hWnd, / 接收消息的窗口句柄,使用HWND_BROADCAST表示所有頂層窗口 UINT Msg, / 發(fā)送消息的代碼 WPARAM wParam, / 指定消息的附加信息 LPARAM lParam / 指定消息的附加信息); 2發(fā)送消息調(diào)用PostMessage()函數(shù)將消息放置到與FindWindow()函數(shù)HWND FindWindow( LPCTSTR lpClassName, /窗口類名,通常為NULL LPCTSTR lpWindowName / 要查找窗口的標題); FindWindow()函數(shù)H
25、WND FindWindow(3消息處理函數(shù)在接收端需要設計一個消息處理函數(shù),它的格式如下:LRESULTOnMyMsg(WPARAM wParam, LPARAM lParam)/ 處理代碼return 0;參數(shù)wParam和lParam用于接收PostMessage()函數(shù)發(fā)送消息時指定的參數(shù)。3消息處理函數(shù)在接收端需要設計一個消息處理函數(shù),它的格式如將消息與其處理函數(shù)映射起來定義消息處理函數(shù)后還要將消息與其處理函數(shù)映射起來。在每個MFC對話框對應的.cpp文件中,都在BEGIN_MESSAGE_MAP宏和END_MESSAGE_MAP()宏之間定義消息與其處理函數(shù)映射的,例如:BEGIN
26、_MESSAGE_MAP(CReceiverDlg, CDialog)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()/AFX_MSG_MAPEND_MESSAGE_MAP()將消息與其處理函數(shù)映射起來定義消息處理函數(shù)后還要將消息與其處BEGIN_MESSAGE_MAP宏BEGIN_MESSAGE_MAP宏用于標識消息映射的開始,其原型如下:BEGIN_MESSAGE_MAP(theClass, baseClass )參數(shù)theClass指定消息映射所屬的類,通常是窗口類;參數(shù)baseClass指定參數(shù)theClass的基類。在BEGIN
27、_MESSAGE_MAP宏和END_MESSAGE_MAP()宏之間添加一條ON_MESSAGE宏用于定義自定義消息及其處理函數(shù)的映射。ON_MESSAGE宏的原型如下:ON_MESSAGE(message, memberFxn )參數(shù)message用于指定自定義消息的代碼,參數(shù)memberFxn指定消息處理函數(shù)。BEGIN_MESSAGE_MAP宏BEGIN_MESSAG【例7.5】設計一個利用自定義消息實現(xiàn)進程間通信的例子。1設計發(fā)送端項目2設計接收端項目【例7.5】設計一個利用自定義消息實現(xiàn)進程間通信的例子。1設計發(fā)送端項目創(chuàng)建一個基于對話框的MFC應用程序Sender,定義自定義消息W
28、M_MY_MESSAGE,代碼如下:#define WM_MY_MESSAGE (WM_USER+999)1設計發(fā)送端項目創(chuàng)建一個基于對話框的MFC應用程序Send單擊“發(fā)送消息”按鈕的代碼void CSenderDlg:OnBnClickedButtonSendmsg()HWND hWnd = :FindWindow(NULL, Receiver); :PostMessage(hWnd,WM_MY_MESSAGE, (WPARAM)999, NULL );單擊“發(fā)送消息”按鈕的代碼void CSenderDlg:2設計接收端項目創(chuàng)建一個基于對話框的MFC應用程序Receiver,定義自定義消
29、息WM_MY_MESSAGE,代碼如下:#define WM_MY_MESSAGE (WM_USER+999)編寫消息處理函數(shù)OnMyMsg(),代碼如下:LRESULT CReceiverDlg:OnMyMsg(WPARAM wParam, LPARAM lParam)char msg100;sprintf(msg, %d, (int)wParam);MessageBox(msg, 收到消息);return 0;2設計接收端項目創(chuàng)建一個基于對話框的MFC應用程序Rece添加自定義消息及其處理函數(shù)的映射BEGIN_MESSAGE_MAP(CReceiverDlg, CDialog) ON_ME
30、SSAGE(WM_MY_MESSAGE, OnMyMsg) / 映射消息和處理函數(shù)/AFX_MSG_MAPEND_MESSAGE_MAP()添加自定義消息及其處理函數(shù)的映射BEGIN_MESSAGE_7.3.2 通過管道進行通信管道(Pipe)是由標準輸入輸出流構成的進程鏈。一個進程的輸出直接作為下一個進程的輸入。每個連接都是一個匿名管道。管道包含一個寫句柄和一個讀句柄。一個進程使用寫句柄向管道里寫入數(shù)據(jù),另一個進程使用讀句柄從管道中讀取數(shù)據(jù)。調(diào)用CreatePipe()函數(shù)可以創(chuàng)建管道,函數(shù)原型如下:BOOL WINAPI CreatePipe( _out PHANDLE hReadPipe
31、,/ 管道的讀句柄 _out PHANDLE hWritePipe, _in LPSECURITY_ATTRIBUTES lpPipeAttributes, _in DWORD nSize);7.3.2 通過管道進行通信管道(Pipe)是由標準輸入輸【例7.6】設計一個利用管道實現(xiàn)進程間通信的例子。主進程Server的代碼如下:#include stdafx.h#include int _tmain(int argc, _TCHAR* argv)HANDLE hRead; / 管道讀句柄HANDLE hWrite; / 管道寫句柄SECURITY_ATTRIBUTES sa; / 設置管道屬性
32、sa.nLength = sizeof(SECURITY_ATTRIBUTES);sa.lpSecurityDescriptor = NULL;sa.bInheritHandle = TRUE;/ 指定管道句柄可以被子進程繼承BOOL bRet = CreatePipe(&hRead, &hWrite, &sa, 0); / 創(chuàng)建匿名管道if (bRet = TRUE)printf(成功創(chuàng)建匿名管道!n);elseprintf(創(chuàng)建匿名管道失敗,錯誤代碼:%dn, GetLastError(); 【例7.6】設計一個利用管道實現(xiàn)進程間通信的例子。接上/ 得到本進程的當前標準輸出,以備將來恢復H
33、ANDLE hTemp = GetStdHandle(STD_OUTPUT_HANDLE); / 設置標準輸出到匿名管道SetStdHandle(STD_OUTPUT_HANDLE, hWrite); STARTUPINFO si; GetStartupInfo(&si); / 獲取本進程的STARTUPINFO結構信息,包括標準設備的句柄PROCESS_INFORMATION pi; / 創(chuàng)建客戶端子進程Client.exe,它會繼承父進程的標準輸出,因此Client.exe的標準輸出是到hWrite管道的bRet = CreateProcess(NULL, Client.exe, NULL
34、, NULL, TRUE, NULL, NULL, NULL, &si, &pi); SetStdHandle(STD_OUTPUT_HANDLE, hTemp); / 恢復本進程的標準輸出if (bRet = TRUE) / 輸入信息printf(成功創(chuàng)建子進程!n); elseprintf(創(chuàng)建子進程失敗,錯誤代碼:%dn, GetLastError(); 接上/ 得到本進程的當前標準輸出,以備將來恢復接上/ 讀管道直至管道關閉char ReadBuf100;DWORD ReadNum;/ 循環(huán)從管道中讀取數(shù)據(jù)while (ReadFile(hRead, ReadBuf, 100, &Re
35、adNum, NULL) ReadBufReadNum = 0;printf(從管道讀取%d字節(jié)數(shù)據(jù):【%s】n, ReadNum, ReadBuf);if (GetLastError() = ERROR_BROKEN_PIPE) / 輸出信息printf(管道被子進程關閉n);elseprintf(讀數(shù)據(jù)錯誤,錯誤代碼:%dn, GetLastError(); return 0;接上/ 讀管道直至管道關閉子進程Client的代碼#include stdafx.h#include #include using namespace std;int _tmain(int argc, _TCHAR*
36、 argv)for (int i = 0; i 10; i+) / 發(fā)送一些數(shù)據(jù)到標準輸出和標準錯誤printf(i = %d; , i); / 打印提示cout 標準輸出: i endl; / 打印到標準輸出cerr 標準錯誤: i endl; / 打印到標準錯誤return 0;子進程Client的代碼#include stdafx.h【例7.6】的運行結果【例7.6】的運行結果7.3.3 使用互斥體HANDLE WINAPI CreateMutex( _in LPSECURITY_ATTRIBUTES lpMutexAttributes,/ 互斥體對象的安全屬性,如果為NULLZ,則互斥
37、體對象不能被子進程繼承 _in BOOL bInitialOwner,/ 初始化互斥對象的所有者 _in LPCTSTR lpName/ 指定互斥對象的名字);如果在不同進程間使用互斥體,則該互斥體對象是全局的。全局互斥體對象的名字必須以“Global”為前綴,而本地互斥體對象的名字則以“Local”為前綴。7.3.3 使用互斥體HANDLE WINAPI Crea【例7.7】設計一個利用互斥體防止運行一個應用程序的多個實例的例子Mutex,代碼如下:int _tmain(int argc, _TCHAR* argv)CreateMutex(NULL,TRUE, GlobalMyMutex00
38、1); if(GetLastError()=ERROR_ALREADY_EXISTS) printf(應用程序已經(jīng)運行!n);exit(0); printf(已進入應用程序n);system(pause);return 0;【例7.7】設計一個利用互斥體防止運行一個應用程序的多個實例第1次運行Mutex.exe的結果第1次運行Mutex.exe的結果7.3.4 通過共享內(nèi)存進行通信每個Windows進程都有其私有的內(nèi)存空間。任何進程都不能修改其他進程的內(nèi)存空間,包括變量和對象等。但是多個進程間可以通過一塊共享內(nèi)存進行通信。共享內(nèi)存是允許多個進程同時訪問的內(nèi)存,不同的進程可以通過共享內(nèi)存進行通訊
39、,也可以避免在不同的程序中保存多余的數(shù)據(jù)備份。通??梢允褂脙?nèi)存映射文件實現(xiàn)共享內(nèi)存,用內(nèi)存映射文件是由一個文件到一塊內(nèi)存的映射。內(nèi)存映射文件與虛擬內(nèi)存有些類似,通過內(nèi)存映射文件可以保留一個地址空間的內(nèi)存區(qū)域,同時將物理存儲器提交給此區(qū)域,內(nèi)存文件映射的物理存儲器來自一個已經(jīng)存在于磁盤上的文件,而且在對該文件進行操作之前必須首先對文件進行映射。使用內(nèi)存映射文件處理存儲于磁盤上的文件時,將不必再對文件執(zhí)行過多的I/O操作,因此,內(nèi)存映射文件在處理大數(shù)據(jù)量的文件時能起到相當重要的作用。7.3.4 通過共享內(nèi)存進行通信每個Windows進程都有CreateFileMapping()函數(shù)HANDLE C
40、reateFileMapping( HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, DWORD flProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, LPCTSTR lpName );CreateFileMapping()函數(shù)HANDLE Cr參數(shù)說明hFile:創(chuàng)建映射對象的文件句柄,如果使用INVALID_HANDLE_VALUE,則在物理內(nèi)存中創(chuàng)建映射對象。lpFileMappingAttributes:被忽略,必須為NULL。flProtect,文
41、件視圖的保護方式。dwMaximumSizeHigh,指定文件映射對象最大大小的高32位。dwMaximumSizeLow,指定文件映射對象最大大小的低32位。lpName,映射對象的名字,如果是全局映射對象,則名字可以以“Global”前綴開始。參數(shù)說明hFile:創(chuàng)建映射對象的文件句柄,如果使用INVAMapViewOfFile()函數(shù)調(diào)用MapViewOfFile()函數(shù)可以將指定的文件視圖映射到調(diào)用進程的地址空間,函數(shù)原型如下:LPVOID MapViewOfFile( HANDLE hFileMappingObject, /文件映射對象的句柄,通常由CreateFileMapping
42、()函數(shù)返回 DWORD dwDesiredAccess, / 對文件視圖的訪問類型 DWORD dwFileOffsetHigh, / 指定開始映射的文件偏移量的高32位 DWORD dwFileOffsetLow, / 指定開始映射的文件偏移量的低32位 DWORD dwNumberOfBytesToMap / 指定文件映射的字節(jié)數(shù)。如果為0,則映射整個文件。);MapViewOfFile()函數(shù)調(diào)用MapViewOfFiOpenFileMapping()函數(shù)HANDLE WINAPI OpenFileMapping( _in DWORD dwDesiredAccess,/ 訪問權限 _i
43、n BOOL bInheritHandle,/ 指定子進程是否可以繼承句柄 _in LPCTSTR lpName/指定要打開指定的文件映射對象的名字);如果函數(shù)執(zhí)行成功,則返回打開指定的文件映射對象句柄;否則返回NULL??梢哉{(diào)用GetLastError()函數(shù)獲取錯誤代碼。OpenFileMapping()函數(shù)HANDLE WINAUnmapViewOfFile()函數(shù)調(diào)用UnmapViewOfFile()函數(shù)可以從調(diào)用進程的地址空間中解除文件視圖的映射。函數(shù)原型如下:BOOL UnmapViewOfFile( LPCVOID lpBaseAddress / 要解除的文件視圖映射的基地址);
44、UnmapViewOfFile()函數(shù)調(diào)用UnmapView【例7.8】計一個創(chuàng)建文件映射對象,并向映射視圖中寫入數(shù)據(jù)的例子Process1,代碼如下:#include stdafx.h#include #include #include #define BUF_SIZE 256/ 共享內(nèi)存的大小TCHAR szName=TEXT(GlobalMyFileMappingObject);/文件映射對象的名字TCHAR szMsg=TEXT(Message from process1); / 向共享內(nèi)存中寫入的數(shù)據(jù)int _tmain(int argc, _TCHAR* argv) HANDLE hMapFile; LPCTSTR pBuf;【例7.8】計一個創(chuàng)建文件映射對象,并向映射視圖中寫入數(shù)據(jù)的接上/ 創(chuàng)建文件映射對象 hMapFile = CreateFileMapping( INVALID_HANDLE_VALUE, / 使用頁文件 NULL, PAGE_READWRITE, / 可讀寫 0, BUF_SIZE, / 文件映射對象的大小 szName); / 文件映射對象的名字 if (hMapFile = NULL) printf(Could not create file ma
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年揚州客運從業(yè)資格證試題答案
- 2024年呼和浩特客運員考試題庫答案
- 2024年承德客運資格證考試題目
- 2024年廣東客運資格證操作考試
- 吉首大學《工程制圖實驗》2021-2022學年第一學期期末試卷
- 吉林藝術學院《素描基礎II》2021-2022學年第一學期期末試卷
- 吉林藝術學院《電影造型語言》2021-2022學年期末試卷
- 平地整田承包協(xié)議書范文模板
- 2022年山東省公務員錄用考試《申論》真題(B類)及答案解析
- 2024年大屏安裝合同簡易協(xié)議書模板
- 國際貿(mào)易理論與實務ppt課件(完整版)
- ICU常用的評估工具(疼痛、鎮(zhèn)靜、譫妄)
- 國際酒店前廳管理手冊前臺接待14-01 外幣兌換Foreign Exchange
- 如何利用記賬改善你企業(yè)
- 藥物化學習題答案
- 校本課程——中外名著閱讀
- 第2章現(xiàn)金流量與資金的時間價值
- 化工企業(yè)承包商安全管理
- 低空飛行基地項目可行性研究報告寫作參考范文
- 【新版】小學《安全在我心中》主題班會.ppt課件
- 2018年人教版九年級英語單詞表
評論
0/150
提交評論