万能的csdner,求助有关进程同步的问题,一个前台模拟shell操控后台文件系统
时间:2011-12-12
来源:互联网
介绍如下:
一个是文件系统进程,成为服务器端,其主要代码是:
建立共享内存
bool create_share_memory() //创建共享内存
{
share_memory_handle=CreateFileMapping((HANDLE)0xFFFFFFFF, NULL,PAGE_READWRITE,0,sizeof(share_memory),_T("share"));//创建
if(share_memory_handle==NULL)
{
cout<<"fail"<<endl;
// ShellExecute(NULL,_T("open"),_T("calc.exe"),NULL,NULL,SW_SHOWNORMAL);
}
if(GetLastError()==ERROR_ALREADY_EXISTS) //如果共享内存已经存在,说明错误
{
cout<<"错误,已经有一个服务器启动"<<endl;
// ShellExecute(NULL,_T("open"),_T("NOTEPAD.EXE"),NULL,NULL,SW_SHOWNORMAL);
return false;
}
// 记载共享内存映像
myshare=(struct share_memory*)MapViewOfFile(share_memory_handle, FILE_MAP_ALL_ACCESS , 0,0,sizeof(share_memory));
//为共享内存创建时间,send事件表示发送命令,finish事件表示执行完毕
send_handle=CreateEvent(NULL,FALSE,FALSE,_T("send"));
finish_handle=CreateEvent(NULL,FALSE,FALSE,_T("finish"));
myshare->num_of_argv=0;
//默认当前处于未执行任何指令状态,顾finish属性设为true
return true;
}
void clear_share_memory()
{
//KillTimer(NULL,1); //清理内存
UnmapViewOfFile(myshare);
CloseHandle(share_memory_handle);
}
同时主函数创建共享内存之后,创建一个线程,线程是一个定时器函数,每隔10ms执行一次
主函数如下:
create_share_memory(); //创建共享内存
DWORD dwThreadId;
CreateThread(NULL, 0, timer_thread, 0, 0, &dwThreadId);
getch();
clear_share_memory();
return 0;
线程函数如下:
int i;
while(true)
{
//线程循环执行,每隔10ms执行一次
if (WaitForSingleObject(send_handle,10)==WAIT_OBJECT_0) //如果收到发送事件
{
//收到客户端准备就绪的消息
//处理客户端数据
cout<<"get send"<<endl;
vector<string> cmdname;
string sub;
if(myshare->num_of_argv>0) //初始化各种命令,参数0表示命令,参数1是第一个路径,参数2是第二个路径
{
sub=myshare->cmdname;
cmdname.push_back(sub);
}
if(myshare->num_of_argv>1)
{
sub=myshare->argv0;
cmdname.push_back(sub);
}
if(myshare->num_of_argv>2)
{
sub=myshare->argv1;
cmdname.push_back(sub);
}
for (i=0;i<12 ;i++) //根据命令执行不同的指令
{
if (!cmdname[0].compare(cmd[i]))
{
break;
}
}
memset(answer,0,sizeof(answer));
//找到匹配的值,分别执行不同的函数
switch (i)
{
case 0: //显示信息
cmd_info(cmdname);
break;
case 1: //创建目录
cmd_md(cmdname);
break;
case 2:
//显示目录的信息
sprintf(answer+strlen(answer),"创建时间 ");
sprintf(answer+strlen(answer),"目录名/文件名 ");
sprintf(answer+strlen(answer),"类型");
sprintf(answer+strlen(answer),"大小(字节)");
sprintf(answer+strlen(answer),"属性\n");
cmd_dir(cmdname,curr_path_id);
break;
case 3: //进入子目录
cmd_cd(cmdname);
break;
case 4:
//删除的目录
cmd_rd(cmdname);
break;
case 5:
//新建的文件
cmd_newfile(cmdname);
break;
case 6:
//读取文件
cmd_cat(cmdname);
break;
case 7:
//复制文件
cmd_copy(cmdname);
break;
case 8:
//删除文件
cmd_del(cmdname);
break;
case 9:
//检查并且修复系统
cmd_check(cmdname);
break;
case 10:
//显示帮助文件
cmd_help(cmdname);
break;
case 11:
//退出系统并保存数据
cmd_exit(cmdname);
break;
default:
break;
}
if(myshare->success)
sprintf(answer+strlen(answer),"执行成功\n");
else
sprintf(answer+strlen(answer),"执行失败\n");
//将执行结果复制到共享内存
sprintf(answer+strlen(answer),"当前目录是%s\n",curr_path);
strcpy(myshare->answer+strlen(myshare->answer),answer);
memset(answer,0,sizeof(answer));
CString a;
a=myshare->answer;
cout<<a<<endl;
//设置执行完毕事件
SetEvent(finish_handle);
//if(myshare->success==false) break;
}
Sleep(10);
}
return 0;
}
共享内存
struct share_memory //共享内存
{
TCHAR cmdname[MAX_CMD_LENGTH+1]; //命令名字
TCHAR argv0[MAX_NAME_LENGTH+1]; //第一个路径
TCHAR argv1[MAX_NAME_LENGTH+1]; //第二个路径
int num_of_argv; //参数数目
bool success; //是否执行成功
TCHAR answer[MAX_ANSWER_LENGTH+1]; //执行结果
bool end; //所有指令执行完毕的 标志
};
另外一个是客户端,是一个前台的mfc,主要功能是获取用户输入的命令,然后通过共享内存传送给文件系统进程,文件系统进程执行完毕之后,再发送给前台的shell,然后显示出来
其主要代码是:
加载共享内存
load_share_memory()
void load_share_memory() //加载共享内存
{
//获得共享内存的句柄
share_memory_handle=OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE,_T("share"));
//映射缓存区视图
myshare=(struct share_memory*)MapViewOfFile( share_memory_handle,FILE_MAP_ALL_ACCESS,0,0,sizeof(share_memory));
if(myshare==NULL)
{
cout<<"共享内存尚未创建,打开服务器端的程序"<<endl;
//共享内存尚未创建,打开服务器端的程序
//ShellExecute(NULL,_T("OPEN"),_T("simdisk.exe"),NULL,SW_HIDE);
HINSTANCE hInstance = ShellExecute(NULL, _T("open"),
_T("simdisk.exe"),
_T("/s"), NULL, SW_HIDE);
Sleep(3000);
cout<<LONG(hInstance)<<endl;
if(LONG(hInstance)<=32)
cout<<"启动失败"<<endl;
//获得共享内存的句柄
share_memory_handle=OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE,_T("share"));
//映射缓存区视图
myshare=(struct share_memory*)MapViewOfFile(share_memory_handle,FILE_MAP_ALL_ACCESS,0,0,sizeof(share_memory));
}
//创建互斥变量,发送事件,结束事件
send_handle=CreateEvent(NULL,FALSE,FALSE,_T("send"));
finish_handle=CreateEvent(NULL,FALSE,FALSE,_T("finish"));
mutex_handle=CreateMutex(NULL,FALSE,_T("mutex"));
}
当用户按下执行按钮的时候,将mfc执行框的文本取出来,逐行执行
代码如下:
void CHappyShellDlg::OnBnClickedButton3()
{
// TODO: 在此添加控件通知处理程序代码
CmdResult="";
current_line=0;
UpdateData(true);
if(CmdList=="")
MessageBox(_T("shell文件为空"));
else
{
// 先将输入内容按照换行符隔开
CmdListVector=CutSentence(CmdList);
//每次取一句执行
while(true)
{
CString sub;
// 如果执行完毕,退出
if(current_line==CmdListVector.size())
{
CmdResult+="执行结束\r\n";
UpdateData(false);
myshare->end=true;
break;
}
vector<CString> cmdname;
cmdname=CutCmd(CmdListVector[current_line++]);
//如果一开始参数太多,则不参与执行过程
if(cmdname.size()>3)
{
sprintf(myshare->answer+strlen(myshare->answer),"执行第%d行\r\n",current_line);
CmdResult+=_T("执行失败,错误信息为:参数数目太多,停止执行\r\n\r\n");
if(current_line!=CmdListVector.size())
CmdResult+=_T("停止运行\r\n");
myshare->success=false;
UpdateData(false);
break;
}
else
{
//如果服务端空闲
if(WaitForSingleObject(mutex_handle,300)==WAIT_OBJECT_0)
{
//则加载命令
memset(myshare->answer,0,sizeof(myshare->answer));
sprintf(myshare->answer,"执行第%d行\r\n",current_line);
myshare->num_of_argv=cmdname.size();
strcpy(myshare->cmdname,cmdname[0].GetBuffer(cmdname[0].GetLength()));
memset( myshare->argv0,0,sizeof(myshare->argv0));
memset( myshare->argv1,0,sizeof(myshare->argv1));
// UpdateData(false);
if(cmdname.size()>1)
{
strcpy( myshare->argv0,cmdname[1].GetBuffer(cmdname[1].GetLength()));
}
if(cmdname.size()>2)
{
strcpy( myshare->argv1,cmdname[2].GetBuffer(cmdname[2].GetLength()));
}
UpdateData(false);
myshare->success=true;
// 设置发送事件
SetEvent(send_handle);
// 如果接收到完成事件,则将结果实现
if(WaitForSingleObject(finish_handle,300)==WAIT_OBJECT_0)
{
cout<<"fuck"<<myshare->answer<<endl;
sub=myshare->answer;
sub.Replace("\n","\r\n");
CmdResult+=sub;
UpdateData(false);
}
// 如果执行有误,则退出不继续执行
if(myshare->success==false&¤t_line!=CmdListVector.size())
{
CmdResult+=_T("停止运行\r\n");
UpdateData(false);
break;
}
ReleaseMutex(mutex_handle);//释放互斥量
}
}
}
}
}
现在的问题是: 对于同样的命令,有时候mfc能够查看到完整的执行结果,有时候不行。
刚启动的时候,执行命令都是正确的,敲了几次命令之后,服务器端的共享内存的结果是正确的,但是
返回到客户端的出现结果却是空的。
比如: 执行check命令
正确的结果应该是: 一些check的信息和执行结束这句话(执行结束这句话是在mfc加入的的)
但是执行错误的结果就变成执行结束这句话而已了,
已经调试了好多天了,通过在服务器端输出共享内存的执行结果没问题,但是传递到mfc的时候就经常出问题,就是传递的变成空的了,求各位帮忙看一下
一个是文件系统进程,成为服务器端,其主要代码是:
建立共享内存
bool create_share_memory() //创建共享内存
{
share_memory_handle=CreateFileMapping((HANDLE)0xFFFFFFFF, NULL,PAGE_READWRITE,0,sizeof(share_memory),_T("share"));//创建
if(share_memory_handle==NULL)
{
cout<<"fail"<<endl;
// ShellExecute(NULL,_T("open"),_T("calc.exe"),NULL,NULL,SW_SHOWNORMAL);
}
if(GetLastError()==ERROR_ALREADY_EXISTS) //如果共享内存已经存在,说明错误
{
cout<<"错误,已经有一个服务器启动"<<endl;
// ShellExecute(NULL,_T("open"),_T("NOTEPAD.EXE"),NULL,NULL,SW_SHOWNORMAL);
return false;
}
// 记载共享内存映像
myshare=(struct share_memory*)MapViewOfFile(share_memory_handle, FILE_MAP_ALL_ACCESS , 0,0,sizeof(share_memory));
//为共享内存创建时间,send事件表示发送命令,finish事件表示执行完毕
send_handle=CreateEvent(NULL,FALSE,FALSE,_T("send"));
finish_handle=CreateEvent(NULL,FALSE,FALSE,_T("finish"));
myshare->num_of_argv=0;
//默认当前处于未执行任何指令状态,顾finish属性设为true
return true;
}
void clear_share_memory()
{
//KillTimer(NULL,1); //清理内存
UnmapViewOfFile(myshare);
CloseHandle(share_memory_handle);
}
同时主函数创建共享内存之后,创建一个线程,线程是一个定时器函数,每隔10ms执行一次
主函数如下:
create_share_memory(); //创建共享内存
DWORD dwThreadId;
CreateThread(NULL, 0, timer_thread, 0, 0, &dwThreadId);
getch();
clear_share_memory();
return 0;
线程函数如下:
int i;
while(true)
{
//线程循环执行,每隔10ms执行一次
if (WaitForSingleObject(send_handle,10)==WAIT_OBJECT_0) //如果收到发送事件
{
//收到客户端准备就绪的消息
//处理客户端数据
cout<<"get send"<<endl;
vector<string> cmdname;
string sub;
if(myshare->num_of_argv>0) //初始化各种命令,参数0表示命令,参数1是第一个路径,参数2是第二个路径
{
sub=myshare->cmdname;
cmdname.push_back(sub);
}
if(myshare->num_of_argv>1)
{
sub=myshare->argv0;
cmdname.push_back(sub);
}
if(myshare->num_of_argv>2)
{
sub=myshare->argv1;
cmdname.push_back(sub);
}
for (i=0;i<12 ;i++) //根据命令执行不同的指令
{
if (!cmdname[0].compare(cmd[i]))
{
break;
}
}
memset(answer,0,sizeof(answer));
//找到匹配的值,分别执行不同的函数
switch (i)
{
case 0: //显示信息
cmd_info(cmdname);
break;
case 1: //创建目录
cmd_md(cmdname);
break;
case 2:
//显示目录的信息
sprintf(answer+strlen(answer),"创建时间 ");
sprintf(answer+strlen(answer),"目录名/文件名 ");
sprintf(answer+strlen(answer),"类型");
sprintf(answer+strlen(answer),"大小(字节)");
sprintf(answer+strlen(answer),"属性\n");
cmd_dir(cmdname,curr_path_id);
break;
case 3: //进入子目录
cmd_cd(cmdname);
break;
case 4:
//删除的目录
cmd_rd(cmdname);
break;
case 5:
//新建的文件
cmd_newfile(cmdname);
break;
case 6:
//读取文件
cmd_cat(cmdname);
break;
case 7:
//复制文件
cmd_copy(cmdname);
break;
case 8:
//删除文件
cmd_del(cmdname);
break;
case 9:
//检查并且修复系统
cmd_check(cmdname);
break;
case 10:
//显示帮助文件
cmd_help(cmdname);
break;
case 11:
//退出系统并保存数据
cmd_exit(cmdname);
break;
default:
break;
}
if(myshare->success)
sprintf(answer+strlen(answer),"执行成功\n");
else
sprintf(answer+strlen(answer),"执行失败\n");
//将执行结果复制到共享内存
sprintf(answer+strlen(answer),"当前目录是%s\n",curr_path);
strcpy(myshare->answer+strlen(myshare->answer),answer);
memset(answer,0,sizeof(answer));
CString a;
a=myshare->answer;
cout<<a<<endl;
//设置执行完毕事件
SetEvent(finish_handle);
//if(myshare->success==false) break;
}
Sleep(10);
}
return 0;
}
共享内存
struct share_memory //共享内存
{
TCHAR cmdname[MAX_CMD_LENGTH+1]; //命令名字
TCHAR argv0[MAX_NAME_LENGTH+1]; //第一个路径
TCHAR argv1[MAX_NAME_LENGTH+1]; //第二个路径
int num_of_argv; //参数数目
bool success; //是否执行成功
TCHAR answer[MAX_ANSWER_LENGTH+1]; //执行结果
bool end; //所有指令执行完毕的 标志
};
另外一个是客户端,是一个前台的mfc,主要功能是获取用户输入的命令,然后通过共享内存传送给文件系统进程,文件系统进程执行完毕之后,再发送给前台的shell,然后显示出来
其主要代码是:
加载共享内存
load_share_memory()
void load_share_memory() //加载共享内存
{
//获得共享内存的句柄
share_memory_handle=OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE,_T("share"));
//映射缓存区视图
myshare=(struct share_memory*)MapViewOfFile( share_memory_handle,FILE_MAP_ALL_ACCESS,0,0,sizeof(share_memory));
if(myshare==NULL)
{
cout<<"共享内存尚未创建,打开服务器端的程序"<<endl;
//共享内存尚未创建,打开服务器端的程序
//ShellExecute(NULL,_T("OPEN"),_T("simdisk.exe"),NULL,SW_HIDE);
HINSTANCE hInstance = ShellExecute(NULL, _T("open"),
_T("simdisk.exe"),
_T("/s"), NULL, SW_HIDE);
Sleep(3000);
cout<<LONG(hInstance)<<endl;
if(LONG(hInstance)<=32)
cout<<"启动失败"<<endl;
//获得共享内存的句柄
share_memory_handle=OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE,_T("share"));
//映射缓存区视图
myshare=(struct share_memory*)MapViewOfFile(share_memory_handle,FILE_MAP_ALL_ACCESS,0,0,sizeof(share_memory));
}
//创建互斥变量,发送事件,结束事件
send_handle=CreateEvent(NULL,FALSE,FALSE,_T("send"));
finish_handle=CreateEvent(NULL,FALSE,FALSE,_T("finish"));
mutex_handle=CreateMutex(NULL,FALSE,_T("mutex"));
}
当用户按下执行按钮的时候,将mfc执行框的文本取出来,逐行执行
代码如下:
void CHappyShellDlg::OnBnClickedButton3()
{
// TODO: 在此添加控件通知处理程序代码
CmdResult="";
current_line=0;
UpdateData(true);
if(CmdList=="")
MessageBox(_T("shell文件为空"));
else
{
// 先将输入内容按照换行符隔开
CmdListVector=CutSentence(CmdList);
//每次取一句执行
while(true)
{
CString sub;
// 如果执行完毕,退出
if(current_line==CmdListVector.size())
{
CmdResult+="执行结束\r\n";
UpdateData(false);
myshare->end=true;
break;
}
vector<CString> cmdname;
cmdname=CutCmd(CmdListVector[current_line++]);
//如果一开始参数太多,则不参与执行过程
if(cmdname.size()>3)
{
sprintf(myshare->answer+strlen(myshare->answer),"执行第%d行\r\n",current_line);
CmdResult+=_T("执行失败,错误信息为:参数数目太多,停止执行\r\n\r\n");
if(current_line!=CmdListVector.size())
CmdResult+=_T("停止运行\r\n");
myshare->success=false;
UpdateData(false);
break;
}
else
{
//如果服务端空闲
if(WaitForSingleObject(mutex_handle,300)==WAIT_OBJECT_0)
{
//则加载命令
memset(myshare->answer,0,sizeof(myshare->answer));
sprintf(myshare->answer,"执行第%d行\r\n",current_line);
myshare->num_of_argv=cmdname.size();
strcpy(myshare->cmdname,cmdname[0].GetBuffer(cmdname[0].GetLength()));
memset( myshare->argv0,0,sizeof(myshare->argv0));
memset( myshare->argv1,0,sizeof(myshare->argv1));
// UpdateData(false);
if(cmdname.size()>1)
{
strcpy( myshare->argv0,cmdname[1].GetBuffer(cmdname[1].GetLength()));
}
if(cmdname.size()>2)
{
strcpy( myshare->argv1,cmdname[2].GetBuffer(cmdname[2].GetLength()));
}
UpdateData(false);
myshare->success=true;
// 设置发送事件
SetEvent(send_handle);
// 如果接收到完成事件,则将结果实现
if(WaitForSingleObject(finish_handle,300)==WAIT_OBJECT_0)
{
cout<<"fuck"<<myshare->answer<<endl;
sub=myshare->answer;
sub.Replace("\n","\r\n");
CmdResult+=sub;
UpdateData(false);
}
// 如果执行有误,则退出不继续执行
if(myshare->success==false&¤t_line!=CmdListVector.size())
{
CmdResult+=_T("停止运行\r\n");
UpdateData(false);
break;
}
ReleaseMutex(mutex_handle);//释放互斥量
}
}
}
}
}
现在的问题是: 对于同样的命令,有时候mfc能够查看到完整的执行结果,有时候不行。
刚启动的时候,执行命令都是正确的,敲了几次命令之后,服务器端的共享内存的结果是正确的,但是
返回到客户端的出现结果却是空的。
比如: 执行check命令
正确的结果应该是: 一些check的信息和执行结束这句话(执行结束这句话是在mfc加入的的)
但是执行错误的结果就变成执行结束这句话而已了,
已经调试了好多天了,通过在服务器端输出共享内存的执行结果没问题,但是传递到mfc的时候就经常出问题,就是传递的变成空的了,求各位帮忙看一下
作者: highway4 发布时间: 2011-12-12
估计还是共享内存数据有问题,你设置断点等调试一下
作者: oyljerry 发布时间: 2011-12-12
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28