新闻资讯
看你所看,想你所想

进程间通讯

进程间通讯一种机制,操作系统进程和线程通过它交来自换数据和消息。IPC 包括本地机制(如 Windows 共享内存)或者网络机制(如 Windows 套接字)。

  • 中文名称 进程间通讯
  • 所属学科 计算机科学与技术

基本简介

  进程间通讯的方式

  Socket,剪切板方法,内存映射文件, 邮槽方法, 命名管道, 匿名管道方法

实现方法

  来自一、Socket的方法

  对于不同机器上且数据量很多的情况会有很大的帮助,但对于同一台机器之间的不同进程之间的通讯就不方便了 (代码量太多)

  进程间通讯的剪切板方法

  a、对于发送端:

 360百科 CString str;

 采立室风杨微 GetDlgItemText(IDC_EDIT1,str);

  HANDLE hGlobal;

  if(this->OpenClipboard())//获取剪切板的资源所有权

  {

  EmptyClipboard();//将剪切板的内容清空

  hGlobal=Gl者立obalAlloc(GMEM_MOVEABLE,str.GetLength()+1);//在堆上分配一块用于存放数据的空间,程序返回一个内存句柄

  char* pBuf=(下条计char*)GlobalLock(hGlobal);//将内存块句柄转化成一住丰格耐顾村型早坚个指针,并将相应的引用根害夜报计数器加一

  strcpy(pBuf,str.GetB裂衡门uffer(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);//将内存块的引用计数器减一

  Clos卫磁尔格帮eClipboard()措点八段着不免旧又;//释放剪切板资源的占用权

  }

  内存映射文件方法

  1、 服务器端代码:

  HANDLE hMapFi信限者天案精宣点势le;

  hMapFile= CreateFileMapping(NULL,NULL,PAGE_R笔杀命当EADWRITE,0,10,"YuanMap");

  if (hM觉理权则临来风道绍apFile == 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);

  PROCESS_INFORMATION pi;

  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);

  --------------------------------------------(完)

转载请注明出处安可林文章网 » 进程间通讯

相关推荐

    声明:此文信息来源于网络,登载此文只为提供信息参考,并不用于任何商业目的。如有侵权,请及时联系我们:fendou3451@163.com