刘家桢 2015-01-03 10:37 采纳率: 0%
浏览 1912

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

题目要求:
两个进程Bob与Jack,能够互相看到对方,若对方进程结束,能够唤醒对方进程。

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

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

我的实现如下:
Bob进程
#include
#include
#include
#include
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
#include
#include
#include
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.但是结果并不如此。

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

  • 写回答

2条回答 默认 最新

  • oyljerry 2015-01-03 13:50
    关注

    其实就是看门狗的概念,只不过是A,B护卫看门狗,可以直接查看对方进程名的方式来做进程守护

    评论

报告相同问题?

悬赏问题

  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号
  • ¥50 安装pyaudiokits失败
  • ¥15 计组这些题应该咋做呀
  • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?
  • ¥15 让node服务器有自动加载文件的功能
  • ¥15 jmeter脚本回放有的是对的有的是错的
  • ¥15 r语言蛋白组学相关问题