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

刘家桢 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.但是结果并不如此。


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

...全文
199 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
  • 打赏
  • 举报
回复
*疑问一:**:是否可以用观察者模式呢?
内容概要:本文围绕基于Basisformer模型的时间序列锂离子电池SOC(State of Charge,荷电状态)预测展开研究,利用PyTorch框架实现深度学习模型的构建与训练。通过将历史充放电数据作为输入,Basisformer能够有效捕捉电池状态的动态变化特征,提升SOC预测精度。文中详细介绍了模型结构设计、数据预处理流程、训练策略及实验结果分析,并与传统方法进行对比,验证了该方法在复杂工况下的优越性与鲁棒性。该研究不仅展示了Basisformer在时序建模中的潜力,也为电池管理系统提供了高精度的状态估计解决方案。; 适合人群:具备一定Python编程基础和深度学习理论知识,熟悉PyTorch框架,从事电池管理系统、新能源汽车或智能预测方向研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于电动汽车、储能系统等领域的电池SOC高精度实时估算;②为电池健康管理(BMS)提供可靠的状态输入;③推动深度学习在时间序列预测中的实际落地,提升现有预测模型的泛化能力与稳定性; 阅读建议:建议读者结合标题为【锂电池SOC估计】【PyTorch】基于Basisformer时间序列锂离子电池SOC预测研究(python代码实现)的资源,重点研读所提供的Python代码,深入理解数据处理方式与模型网络结构的设计思路,尝试调整超参数以观察对预测性能的影响,从而全面掌握Basisformer在时序建模中的优势、适用边界及工程化实现路径。

3,881

社区成员

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

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