進程間通訊

進程間通訊

進程間通訊一種機制,作業系統進程和執行緒通過它交換數據和訊息。IPC 包括本地機制(如 Windows 共享記憶體)或網路機制(如 Windows 套接字)。

基本介紹

基本介紹,實現方法,

基本介紹

進程間通訊的方式
Socket,剪下板方法,記憶體映射檔案, 郵槽方法, 命名管道, 匿名管道方法

實現方法

一、Socket的方法
對於不同機器上且數據量很多的情況會有很大的幫助,但對於同一台機器之間的不同進程之間的通訊就不方便了 (代碼量太多)
進程間通訊的剪下板方法
a、對於傳送端:
CString str;
GetDlgItemText(IDC_EDIT1,str);
HANDLE hGlobal;
if(this->OpenClipboard())//獲取剪下板的資源所有權
{
EmptyClipboard();//將剪下板的內容清空
hGlobal=GlobalAlloc(GMEM_MOVEABLE,str.GetLength()+1);//在堆上分配一塊用於存放數據的空間,程式返回一個記憶體句柄
char* pBuf=(char*)GlobalLock(hGlobal);//將記憶體塊句柄轉化成一個指針,並將相應的引用計數器加一
strcpy(pBuf,str.GetBuffer(str.GetLength()));//將字元串拷入指定的記憶體塊中
GlobalUnlock(hGlobal);//將引用計數器數字減一
::SetClipboardData(CF_TEXT,hGlobal);//將存放有數據的記憶體塊放入剪下板的資源管理中
::CloseClipboard();//釋放剪下板的資源占用權
}
b、對於客戶端
if(this->OpenClipboard())//獲取剪下板的資源所有權
{
HANDLE hGlobal=::GetClipboardData(CF_TEXT);從剪下板中取出一個記憶體的句柄
char* pBuf=(char*)GlobalLock(hGlobal);//將記憶體句柄值轉化為一個指針,並將記憶體塊的引用計數器加一
SetDlgItemText(IDC_EDIT2,pBuf);
GlobalUnlock(hGlobal);//將記憶體塊的引用計數器減一
CloseClipboard();//釋放剪下板資源的占用權
}
進程間通訊
記憶體映射檔案方法
1、 伺服器端代碼:
HANDLE hMapFile;
hMapFile= CreateFileMapping(NULL,NULL,PAGE_READWRITE,0,10,"YuanMap");
if (hMapFile == NULL)
{
AfxMessageBox("CreateFileMapping出錯!");
return;
}
LPVOID pFile;
pFile= MapViewOfFile(hMapFile,FILE_MAP_WRITE|FILE_MAP_READ,0,0,0);
if (pFile == NULL)
{
AfxMessageBox("MapViewOfFile出錯!");
return;
}
CString str;
GetDlgItemText(IDC_EDIT1,str);
strcpy((char*)pFile,str.GetBuffer(str.GetLength()));
//CloseHandle(hMapFile); //不能加,否則客戶端收不到,所以一般會將這個句柄作為一個全局變數
2、 客戶機端代碼:
HANDLE hMap;
hMap= OpenFileMapping(FILE_MAP_READ|FILE_MAP_WRITE,
TRUE,
"YuanMap");
LPVOID pVoid;
pVoid=::MapViewOfFile(hMap,FILE_MAP_READ,0,0,0);
CString str=(char*)pVoid;
SetDlgItemText(IDC_EDIT1,str);
UnmapViewOfFile(pVoid);
CloseHandle(hMap);
進程間通訊的郵槽方法
1、 郵槽採用的是一種廣播機制。
2、 郵槽採用的是一種直接基於檔案系統開發而成,所以它不依賴於某種具體的網路協定。
3、 郵槽每次傳送的訊息長度不能長於422位元組。
4、 傳送端代碼如下:(客戶端)
HANDLE hslot;
hslot=CreateFile("\\\\.\\mailslot\\myslot",GENERIC_WRITE,
FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,
NULL);
if(!hslot)
{
MessageBox("打開郵槽失敗!");
return;
}
char *pBuf="專業的程式語言培訓";
DWORD dwWrite;
WriteFile(hslot,pBuf,strlen(pBuf)+1,&dwWrite,NULL);
CloseHandle(hslot);
5、 接收端代碼如下:(伺服器端)
HANDLE hMail;
hMail=CreateMailslot("\\\\.\\mailslot\\myslot",0,
MAILSLOT_WAIT_FOREVER,NULL);
if(INVALID_HANDLE_VALUE==hMail)
{
MessageBox("創建郵槽失敗!");
return;
}
HANDLE hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
OVERLAPPED ovlap;
ZeroMemory(&ovlap,sizeof(ovlap));
ovlap.hEvent=hEvent;
char buf[200];
DWORD dwRead;
if(FALSE==ReadFile(hMail,buf,200,&dwRead,&ovlap))
{
if(ERROR_IO_PENDING!=GetLastError())
{
MessageBox("讀取操作失敗!");
CloseHandle(hMail);
return;
}
}
WaitForSingleObject(hEvent,INFINITE);
MessageBox(buf);
ResetEvent(hEvent);
CloseHandle(hMail);
進程間通訊的命令管道方法
A、對於傳送端代碼如下:
HANDLE handle;
handle=CreateNamedPipe("\\\\.\\pipe\\MyPipe",
PIPE_ACCESS_DUPLEX,PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
1,0,0,1000,NULL);//創建一個命名管道連結
ConnectNamedPipe(handle,NULL);//在命名管道實例上監聽客戶機連結請求
char buf[200]="http://www.it315.org";
DWORD dwWrite;
WriteFile(handle,buf,strlen(buf)+1,&dwWrite,NULL);//往管道里寫數據
CloseHandle(handle);//關閉管道
B、對於接收端代碼如下:
HANDLE hNamedPipe;
WaitNamedPipe("\\\\.\\pipe\\MyPipe",NMPWAIT_WAIT_FOREVER);//等候一個命名管道實例可供自己使用
hNamedPipe=CreateFile("\\\\.\\pipe\\MyPipe",GENERIC_READ,FILE_SHARE_READ,
NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);//建立與命名管道的連結
char buf[200];
DWORD dwRead;
ReadFile(hNamedPipe,buf,200,&dwRead,NULL);//從命名管道中讀取數據
MessageBox(buf);
CloseHandle(hNamedPipe);//關閉與命名管道伺服器的連結
進程間通訊的匿名管道方法
父進程:
A、對於父進程中創建一個管道代碼如下:
SECURITY_ATTRIBUTES sa;
sa.nLength=sizeof(sa);
sa.bInheritHandle=TRUE;
sa.lpSecurityDescriptor=NULL;
if(FALSE==CreatePipe(&hRead,&hWrite,&sa,0))//創建一個匿名的管道,得到一個用於從管道讀取的句柄,一個用於向管道寫數據用的句柄
{
MessageBox("Create pipe failed!");
return;
}
STARTUPINFO sui;
ZeroMemory(&sui,sizeof(sui));
sui.cb=sizeof(sui);
sui.dwFlags=STARTF_USESTDHANDLES;
sui.hStdInput=hRead;
sui.hStdOutput=hWrite;
sui.hStdError=GetStdHandle(STD_ERROR_HANDLE);
CreateProcess("..\\PipeCli\\Debug\\PipeCli.exe",NULL,
NULL,NULL,TRUE,CREATE_DEFAULT_ERROR_MODE,/*0*/
NULL,NULL,&sui,&pi);//創建一個新的子進程,並將準備好的句柄信息傳給子進程
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
B、父進程中從管道讀取代碼如下:
char buf[200];
DWORD dwRead;
ReadFile(hRead,buf,200,&dwRead,NULL);
MessageBox(buf);
C、父進程中往管道寫入代碼如下:
char buf[200]="專業的程式語言培訓";
DWORD dwWrite;
WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL);
子進程:
首先得到用於管道讀取與寫入用的句柄值(最好是放在視圖的初始化更新函數裡)
hRead=GetStdHandle(STD_INPUT_HANDLE);
hWrite=GetStdHandle(STD_OUTPUT_HANDLE);
讀取部分代碼:
char buf[200];
DWORD dwRead;
ReadFile(hRead,buf,200,&dwRead,NULL);
MessageBox(buf);
寫入部分代碼:
char buf[200]="http://www.it315.org";
DWORD dwWrite;
WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL);
--------------------------------------------(完)

相關詞條

熱門詞條

聯絡我們