一个有意思的进程通信的小问题

刘家桢 2015-01-03 06:41:43
**题目要求:**
两个进程Bob与Jack,能够互相看到对方,若对方进程结束,能够唤醒对方进程。

**我的思路:**
两个进程利用一个公共文件mail.txt,互斥地访问对方的状态,若发现对方不在线,则启动对方进程。mail文件中 1表示进程在线,0表示进程不在线。

**现象:**
进程间可以相互启动,但总是莫名终止,并且终止后mail文件中的两个进程的状态并不都为0.

**我的实现如下:**
**Bob进程**
#include <iostream>
#include <fstream>
#include <windows.h>
#include <time.h>
using namespace std;

int main()
{
//同步信号量
HANDLE Bob=CreateSemaphore(NULL,1,1,"Bob");
HANDLE Jack=CreateSemaphore(NULL,1,1,"Jack");
HANDLE Exit=CreateSemaphore(NULL,1,1,"Exit");

//共享文件
fstream mail;
mail.open("mail.txt");
if(mail)
cout<<"Bob:let's begin talking"<<endl;
else
{
mail.open("mail.txt",fstream::app);
}

//Bob在线
WaitForSingleObject(Bob,INFINITE);
{
mail.seekp(10*sizeof(char),fstream::beg);
mail<<1;
}
ReleaseSemaphore(Bob,1,NULL);

//读取Jack的状态
int areyouhere = 0;
WaitForSingleObject(Jack,INFINITE);
{
mail.seekg(0,fstream::beg);
mail>>areyouhere;
}
ReleaseSemaphore(Jack,1,NULL);
STARTUPINFO si={sizeof(si)};
PROCESS_INFORMATION pi;
si.dwFlags=STARTF_USESHOWWINDOW;
si.wShowWindow=TRUE;

//与Jack打招呼或者唤醒jack
if(areyouhere == 1)
{
cout<<"Bob:I see you"<<endl;
}
else
{
cout<<"Bob:wake up,dude"<<endl;
CreateProcess("Iseeyoutoo.exe",NULL,NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi);
}

//Bob退出前,检查Jack是否在线
WaitForSingleObject(Exit,INFINITE);
{
//Bob修改状态为退出
WaitForSingleObject(Bob,INFINITE);
{
mail.seekp(10*sizeof(char),fstream::beg);
mail<<0;
ReleaseSemaphore(Bob,1,NULL);
}
//唤醒Jack或与Jack告别
WaitForSingleObject(Jack,INFINITE);
{
mail.seekg(0,fstream::beg);
mail>>areyouhere;
}
ReleaseSemaphore(Jack,1,NULL);
if(areyouhere == 1)
{
cout<<"Bob:I will go"<<endl;
}
else
{
cout<<"Bob:wake up,dude"<<endl;
CreateProcess("Iseeyoutoo.exe",NULL,NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi);
}

}
ReleaseSemaphore(Exit,1,NULL);

//Bob退出
cout<<"Bob:bye-bye"<<endl;
mail.close();
CloseHandle(Bob);
CloseHandle(Jack);
CloseHandle(Exit);
}

**Jack进程:**
#include <iostream>
#include <fstream>
#include <windows.h>
#include <time.h>
using namespace std;

int main()
{
//同步信号量
HANDLE Bob=CreateSemaphore(NULL,1,1,"Bob");
HANDLE Jack=CreateSemaphore(NULL,1,1,"Jack");
HANDLE Exit=CreateSemaphore(NULL,1,1,"Exit");

//共享文件
fstream mail;
mail.open("mail.txt");
if (mail)
cout<<"Jack:let's begin talking"<<endl;
else
{
mail.open("mail.txt",fstream::app);
}

//Jack在线
WaitForSingleObject(Jack,INFINITE);
{
mail.seekp(0,fstream::beg);
mail<<1;
}
ReleaseSemaphore(Jack,1,NULL);

//读取Bob状态
int areyouhere = 0;
WaitForSingleObject(Bob,INFINITE);
{
mail.seekg(10*sizeof(char),fstream::beg);
mail>>areyouhere;
}
ReleaseSemaphore(Bob,1,NULL);
STARTUPINFO si={sizeof(si)};
PROCESS_INFORMATION pi;
si.dwFlags=STARTF_USESHOWWINDOW;
si.wShowWindow=TRUE;

//唤醒Bob或者打招呼
if (areyouhere == 1)
cout<<"Jack:I see you"<<endl;
else
{
cout<<"Jack:wake up,brother"<<endl;
CreateProcess("Iseeyou.exe",NULL,NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi);
}
cout<<"Jack:Iseeyou,byebye"<<endl;

//Jack即将退出,检查Bob是否在线
WaitForSingleObject(Exit,INFINITE);
{
//Jack修改状态为退出
WaitForSingleObject(Jack,INFINITE);
{
mail.seekp(0,fstream::beg);
mail<<0;
}
ReleaseSemaphore(Jack,1,NULL);

//唤醒Bob或者告别
WaitForSingleObject(Bob,INFINITE);
{
mail.seekg(10*sizeof(char),fstream::beg);
mail>>areyouhere;
}
ReleaseSemaphore(Bob,1,NULL);
if (areyouhere == 1)
cout<<"Jack:I will go"<<endl;
else
{
cout<<"Jack:wake up,brother"<<endl;
CreateProcess("Iseeyou.exe",NULL,NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi);
}
}
ReleaseSemaphore(Exit,1,NULL);

//Jack退出
cout<<"Jack:byebye"<<endl;
mail.close();
CloseHandle(Bob);
CloseHandle(Jack);
CloseHandle(Exit);
}

**疑问一:**
在Bob结束前,Bob询问Jack的状态,若Jack不在线,则唤醒Jack。
Jack的退出代码段与Bob相同。
因为有Exit互斥量,所以两个进程同一时刻只有一个能够退出,当另一个再退出时,应当能检测出“朋友进程”的消失,唤醒对方。但是运行结果并不如此。

**疑问二:**
在上一段代码中,Bob修改了他的状态。Jack在退出时同样如此修改。
那么即使程序出错,在两个进程结束后,mail文件中显示的两个进程状态应该都为0.但是结果并不如此。


有兴趣的朋友可以给出自己的方法。
希望大神能指出我的错误。

...全文
168 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
hlx_beat 2015-01-18
  • 打赏
  • 举报
回复
高端 新发明。。。
赵4老师 2015-01-04
  • 打赏
  • 举报
回复
zhuyf87 2015-01-04
  • 打赏
  • 举报
回复
使用共享内存实现过类似的功能。
勤奋的小游侠 2015-01-04
  • 打赏
  • 举报
回复
利用socket通信怎么样?
baihacker 2015-01-03
  • 打赏
  • 举报
回复
。。。居然有人邀请我回答问题了。。。 IO操作对其它进程不一定马上可见,或许flush一下会起作用。 目测使用文件也就是起个原子寄存器的作用,使用共享内存(或者再使用一个信号量或者事件)试试呢?
Evankaka 2015-01-03
  • 打赏
  • 举报
回复
*疑问一:**:是否可以用观察者模式呢?

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧