进程间通信的问题(C++高手进)
楼主接触C较少,所以这个实验不会做..要求是:写俩程序P1,P2.P1运行创建子进程P2(即在P1中调用P2),其中P1为父进程,P2由P1创建,为P1子进程.P1提供输...
楼主接触C较少,所以这个实验不会做..
要求是:写俩程序P1,P2.P1运行创建子进程P2(即在P1中调用P2),其中P1为父进程,P2由P1创建,为P1子进程.
P1提供输入界面,读入用户输入.用户每输入一行字符,P1首先将字符放到和P2共享的内存缓冲区中,然后通过消息通知P2(消息自己定义)
P2提供显示界面,每接受到P1的一个消息,先从缓冲区读入数据,然后显示,并发P1消息,通知P1数据处理完毕.
P1在接受到P2的消息后,提示用户.以此类推.
所提供的主要函数:CreateProcess,CreateFileMapping,OpenFileMapping,FlushViewOfFile,UnmapViewOfFile,SendMessage,GetMessage.
求注释求程序,重赏 展开
要求是:写俩程序P1,P2.P1运行创建子进程P2(即在P1中调用P2),其中P1为父进程,P2由P1创建,为P1子进程.
P1提供输入界面,读入用户输入.用户每输入一行字符,P1首先将字符放到和P2共享的内存缓冲区中,然后通过消息通知P2(消息自己定义)
P2提供显示界面,每接受到P1的一个消息,先从缓冲区读入数据,然后显示,并发P1消息,通知P1数据处理完毕.
P1在接受到P2的消息后,提示用户.以此类推.
所提供的主要函数:CreateProcess,CreateFileMapping,OpenFileMapping,FlushViewOfFile,UnmapViewOfFile,SendMessage,GetMessage.
求注释求程序,重赏 展开
7个回答
展开全部
//////////////////////////////////////DDE回调函数; HDDEDATA CALLBACK DdeCallback(UINT wType,UINT wFmt,HCONV hConv,HSZ Topic,HSZ Item, HDDEDATA hData,DWORD lData1,DWORD lData2) { int I ; char tmp[255]; switch(wType) { case XTYP_ADVSTART: case XTYP_CONNECT://请求连接; return ((HDDEDATA)TRUE);//允许; case XTYP_ADVDATA: //有数据到来; for(I=0;I<NITEM;I++) if(Item==hszItem[I]) { DdeGetData(hData,(PBYTE)tmp,255,0);//取得数据; switch(I) { case 0: SetDlgItemText(hWnd,IDC_STATIC2,tmp); break; case 1: SetDlgItemText(hWnd,IDC_STATIC3,tmp); break; } } return ((HDDEDATA)DDE_FACK);//回执; case XTYP_ADVREQ: case XTYP_REQUEST://数据请求; for(I=0;I<NITEM;I++) if(Item==hszItem[I]) return(DdeCreateDataHandle(idlnst,(PBYTE)(LPCTSTR)ServerData[I], ServerData[I].GetLength()+1,0,Item,wFmt,0)); } return(0); } ///////////////////////////////////////////////////// CddedemoDlg.cpp CDdedemoDlg::CDdedemoDlg(CWnd* pParent /*=NULL*/) : CDialog(CDdedemoDlg::IDD, pParent) { //{{AFX_DATA_INIT(CDdedemoDlg) m_edit = _T(""); //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CDdedemoDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDdedemoDlg) DDX_Text(pDX, IDC_EDIT1, m_edit); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDdedemoDlg, CDialog) //{{AFX_MSG_MAP(CDdedemoDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_WM_TIMER() ON_WM_DESTROY() ON_EN_CHANGE(IDC_EDIT1, OnChangeEdit1) //}}AFX_MSG_MAP END_MESSAGE_MAP() //////////////////////////////////////////CDdedemoDlg message handlers BOOL CDdedemoDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here hWnd=m_hWnd; if (DdeInitialize(&idlnst,(PFNCALLBACK)DdeCallback,APPCMD_FILTERINITS| CBF_FAIL_EXECUTES|CBF_SKIP_CONNECT_CONFIRMS|CBF_FAIL_SELFCONNECTIONS| CBF_FAIL_POKES,0)) { MessageBox("DDE SERVER初始化失败!"); return FALSE; } hlnst=AfxGetApp()->m_hInstance; //创建DDE string hszApp=DdeCreateStringHandle(idlnst,szApp,0); hszTopic=DdeCreateStringHandle(idlnst,szTopic,0); for(int I=0;I<NITEM;I++) hszItem[I]=DdeCreateStringHandle(idlnst,pszItem[I],0); //注册服务; DdeNameService(idlnst,hszApp,0,DNS_REGISTER); bConnect=FALSE; SetTimer(1,1000,NULL);//开始定时; return TRUE; // return TRUE unless you set the focus to a control } void CDdedemoDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CDdedemoDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CDdedemoDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CDdedemoDlg::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default count++; ServerData[1].Format("%d",count); SetDlgItemText(IDC_STATIC1,ServerData[1]); DdePostAdvise(idlnst,hszTopic,hszItem[1]);//通知更新; if(!bConnect)//如果没有建立连接 { hConv=DdeConnect(idlnst,hszApp,hszTopic,NULL); //连接服务器端; if(hConv) //如果建立成功 { DWORD dwResult; bConnect=TRUE; for(int I=0;I<NITEM;I++) DdeClientTransaction(NULL,0,hConv,hszItem[I],CF_TEXT,XTYP_ADVSTART, TIMEOUT_ASYNC,&dwResult); } } CDialog::OnTimer(nIDEvent); } void CDdedemoDlg::OnDestroy() { CDialog::OnDestroy(); // TODO: Add your message handler code here KillTimer(1);//销毁定时; DdeNameService(idlnst,0,0,DNS_UNREGISTER);//注销服务; DdeFreeStringHandle(idlnst,hszApp); DdeFreeStringHandle(idlnst,hszTopic); for(int I=0;I<NITEM;I++) DdeFreeStringHandle(idlnst,hszItem[I]); DdeUninitialize(idlnst); } void CDdedemoDlg::OnChangeEdit1() { // TODO: If this is a RICHEDIT control, the control will not // send this notification unless you override the CDialog::OnInitDialog() // function and call CRichEditCtrl().SetEventMask() // with the ENM_CHANGE flag ORed into the mask. // TODO: Add your control notification handler code here UpdateData(); ServerData[0]=m_edit; DdePostAdvise(idlnst,hszTopic,hszItem[0]); //通知DDE更新该数据项目; }
展开全部
/*
windows,vs2010平台,进程间通信,图方便将两个进程都写在这一个源代码里面了
*/
#include <Windows.h>
int _tmain(int argc, _TCHAR* argv[])
{
//是否是子进程标志
bool isChildProcess = false;
//安全属性描述符,定义来让句柄可以在子进程中可以继承
SECURITY_ATTRIBUTES sa;
memset(&sa,0x0,sizeof(sa));
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
//信号量,用于通知子进程已经有输入数据了,主进程中是创建,子进程中是打开
HANDLE hSemaphore = ::CreateSemaphore(&sa,0,100,_T("{F8166D73-5BE5-4659-B024-87D9A7B18069}"));
if ( NULL == hSemaphore )
{
perror("主进程中创建/子进程中打开信号量失败.");
return 0;
}
else if ( NULL != hSemaphore && ERROR_ALREADY_EXISTS == ::GetLastError() )
{
//这个是子进程
isChildProcess = true;
}
//创建文件映射(主进程中调用此函数是真实地创建,而子进程中调用此函数时相当于打开)
HANDLE hFileMap = ::CreateFileMapping(
INVALID_HANDLE_VALUE,//使用内存的分页中创建文件映射
&sa,//指定文件映射句柄可继承,如果不指定可继承,可以在子进程中用OpenFileMapping()函数打开已创建的文件映射
PAGE_READWRITE,//指定内存映射区访问保护标志
0,//内存大小高位
1024,//内存大小低位
_T("{99A2E4DA-A6A5-41DD-9767-2824D45AD8BA}")//映射名称
);
if ( NULL == hFileMap )
{
perror("主进程中创建/子进程中打开内存文件映射失败.");
::CloseHandle(hSemaphore);
return 0;
}
else if ( NULL != hFileMap && ERROR_ALREADY_EXISTS == ::GetLastError() )
{
//这个是子进程
isChildProcess = true;
}
//映射内存文件
LPVOID pMemFile = NULL;
//主进程/子进程中映射视图,因为子进程中hFileMap是打开同名的文件映射句柄而来的,所以虽然主进程和子进程都调用映射视图的函数MapViewOfFile(),
//但是在这两个进程中返回的pMemFile的地址是一样的
pMemFile =::MapViewOfFile(
hFileMap,
FILE_MAP_READ | FILE_MAP_WRITE,
0,
0,
1024
);
if ( NULL == pMemFile )
{
perror("主进程/子进程中创建映射视图失败.");
::CloseHandle(hSemaphore);
return 0;
}
//主进程中创建子进程
if ( ! isChildProcess )
{
TCHAR currentExeFileName[MAX_PATH];
::GetModuleFileName(NULL,currentExeFileName,MAX_PATH);
//主进程里创建子进程
PROCESS_INFORMATION pInfoChild;
memset(&pInfoChild,0x0,sizeof(pInfoChild));
STARTUPINFO stInfo;
memset(&stInfo,0x0,sizeof(stInfo));
stInfo.cb = sizeof(stInfo);
if ( ! ::CreateProcess(
currentExeFileName,//子进程名,就是再运行一个本程序的实例
NULL,//命令行
&sa,//子进程安全属性
&sa,//子进程的线程安全属性
TRUE,//是否可继承主进程句柄
NORMAL_PRIORITY_CLASS,//子进程创建标志
NULL,//使用默认环境变量
NULL,//使用默认起始位置
&stInfo,//子进程启动参数
&pInfoChild//子进程信息
) )
{
perror("主进程中创建子进程失败.");
::CloseHandle(hSemaphore);
return 0;
}
printf("创建子进程成功\n");
char inputStr[1024] = {'0x0'};
while ( strcmp(inputStr,"exit") != 0 )
{
fflush(stdin);
memset(inputStr,0x0,sizeof(inputStr));
Sleep(200);//防止显示出现错乱
printf("(主)输入一行字符(输入exit退出) = ");
scanf("%s",inputStr);
strcpy((char *)pMemFile,inputStr);
::ReleaseSemaphore(hSemaphore,1,NULL);
}
//等待子进程收到exit退出后再退出
::WaitForSingleObject(pInfoChild.hProcess,0);
::UnmapViewOfFile(pMemFile);
::CloseHandle(hFileMap);
::CloseHandle(hSemaphore);
return 0;
}
else
{
//子进程读取数据并显示
char inputStr[1024] = {'0x0'};
while ( strcmp(inputStr,"exit") != 0 )
{
::WaitForSingleObject(hSemaphore,INFINITE);
memset(inputStr,0x0,sizeof(inputStr));
strcpy(inputStr,(char *)pMemFile);
printf("\n(子)接收数据 = %s\n",inputStr);
}
//子进程收到exit退出后退出
::UnmapViewOfFile(pMemFile);
::CloseHandle(hFileMap);
::CloseHandle(hSemaphore);
return 0;
}
return 0;
}
windows,vs2010平台,进程间通信,图方便将两个进程都写在这一个源代码里面了
*/
#include <Windows.h>
int _tmain(int argc, _TCHAR* argv[])
{
//是否是子进程标志
bool isChildProcess = false;
//安全属性描述符,定义来让句柄可以在子进程中可以继承
SECURITY_ATTRIBUTES sa;
memset(&sa,0x0,sizeof(sa));
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
//信号量,用于通知子进程已经有输入数据了,主进程中是创建,子进程中是打开
HANDLE hSemaphore = ::CreateSemaphore(&sa,0,100,_T("{F8166D73-5BE5-4659-B024-87D9A7B18069}"));
if ( NULL == hSemaphore )
{
perror("主进程中创建/子进程中打开信号量失败.");
return 0;
}
else if ( NULL != hSemaphore && ERROR_ALREADY_EXISTS == ::GetLastError() )
{
//这个是子进程
isChildProcess = true;
}
//创建文件映射(主进程中调用此函数是真实地创建,而子进程中调用此函数时相当于打开)
HANDLE hFileMap = ::CreateFileMapping(
INVALID_HANDLE_VALUE,//使用内存的分页中创建文件映射
&sa,//指定文件映射句柄可继承,如果不指定可继承,可以在子进程中用OpenFileMapping()函数打开已创建的文件映射
PAGE_READWRITE,//指定内存映射区访问保护标志
0,//内存大小高位
1024,//内存大小低位
_T("{99A2E4DA-A6A5-41DD-9767-2824D45AD8BA}")//映射名称
);
if ( NULL == hFileMap )
{
perror("主进程中创建/子进程中打开内存文件映射失败.");
::CloseHandle(hSemaphore);
return 0;
}
else if ( NULL != hFileMap && ERROR_ALREADY_EXISTS == ::GetLastError() )
{
//这个是子进程
isChildProcess = true;
}
//映射内存文件
LPVOID pMemFile = NULL;
//主进程/子进程中映射视图,因为子进程中hFileMap是打开同名的文件映射句柄而来的,所以虽然主进程和子进程都调用映射视图的函数MapViewOfFile(),
//但是在这两个进程中返回的pMemFile的地址是一样的
pMemFile =::MapViewOfFile(
hFileMap,
FILE_MAP_READ | FILE_MAP_WRITE,
0,
0,
1024
);
if ( NULL == pMemFile )
{
perror("主进程/子进程中创建映射视图失败.");
::CloseHandle(hSemaphore);
return 0;
}
//主进程中创建子进程
if ( ! isChildProcess )
{
TCHAR currentExeFileName[MAX_PATH];
::GetModuleFileName(NULL,currentExeFileName,MAX_PATH);
//主进程里创建子进程
PROCESS_INFORMATION pInfoChild;
memset(&pInfoChild,0x0,sizeof(pInfoChild));
STARTUPINFO stInfo;
memset(&stInfo,0x0,sizeof(stInfo));
stInfo.cb = sizeof(stInfo);
if ( ! ::CreateProcess(
currentExeFileName,//子进程名,就是再运行一个本程序的实例
NULL,//命令行
&sa,//子进程安全属性
&sa,//子进程的线程安全属性
TRUE,//是否可继承主进程句柄
NORMAL_PRIORITY_CLASS,//子进程创建标志
NULL,//使用默认环境变量
NULL,//使用默认起始位置
&stInfo,//子进程启动参数
&pInfoChild//子进程信息
) )
{
perror("主进程中创建子进程失败.");
::CloseHandle(hSemaphore);
return 0;
}
printf("创建子进程成功\n");
char inputStr[1024] = {'0x0'};
while ( strcmp(inputStr,"exit") != 0 )
{
fflush(stdin);
memset(inputStr,0x0,sizeof(inputStr));
Sleep(200);//防止显示出现错乱
printf("(主)输入一行字符(输入exit退出) = ");
scanf("%s",inputStr);
strcpy((char *)pMemFile,inputStr);
::ReleaseSemaphore(hSemaphore,1,NULL);
}
//等待子进程收到exit退出后再退出
::WaitForSingleObject(pInfoChild.hProcess,0);
::UnmapViewOfFile(pMemFile);
::CloseHandle(hFileMap);
::CloseHandle(hSemaphore);
return 0;
}
else
{
//子进程读取数据并显示
char inputStr[1024] = {'0x0'};
while ( strcmp(inputStr,"exit") != 0 )
{
::WaitForSingleObject(hSemaphore,INFINITE);
memset(inputStr,0x0,sizeof(inputStr));
strcpy(inputStr,(char *)pMemFile);
printf("\n(子)接收数据 = %s\n",inputStr);
}
//子进程收到exit退出后退出
::UnmapViewOfFile(pMemFile);
::CloseHandle(hFileMap);
::CloseHandle(hSemaphore);
return 0;
}
return 0;
}
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
这是典型的消费者和生产者的模式!
给出的几个函数无非是想让你用内存映射文件方法作为缓冲区(临界资源),然后通过给进程发送消息就OK了。
主要是在CreateFileMapping的时候要戴上名字,以方便另一个进程可以OpenFileMapping并使用。
给出的几个函数无非是想让你用内存映射文件方法作为缓冲区(临界资源),然后通过给进程发送消息就OK了。
主要是在CreateFileMapping的时候要戴上名字,以方便另一个进程可以OpenFileMapping并使用。
追问
其实是完全不懂操作啊- -表示楼主一直没深究过C++,连给给出的函数参数赋值还一知半解..伤不起啊
追答
查MSDN。再不懂的话就去论坛或者博客上看看!
不算太难!
本回答被提问者和网友采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
提醒楼主,这个找操作系统的书看个上午,你就可以编代码。具体怎么写,哥忘了。其实注意函数原型就差不多了。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
MFC做的吗?
我也不会~~
我也不会~~
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询