首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

问个有关问题!createprocess和两条管道pipe通信造成的混乱

2013-04-21 
问个问题!createprocess和两条管道pipe通信造成的混乱!描述差不多是这样的,我要在main下边调用createproce

问个问题!createprocess和两条管道pipe通信造成的混乱!
描述差不多是这样的,我要在main下边调用createprocess创建一个ffplay.exe,在设置STARTUPINFO结构的时候:
STARTUPINFO siStartInfo;
ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
siStartInfo.cb = sizeof(STARTUPINFO); 
siStartInfo.hStdError  = g_hChildStd_Error;// 错误输出句柄
siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;// 输出句柄
siStartInfo.hStdInput  = g_hChildStd_IN_Rd;// 输入句柄
siStartInfo.dwFlags   |= STARTF_USESTDHANDLES;

当然这两个g_hChildStd_IN_Rd和g_hChildStd_OUT_Wr是绑定起来的:
if ( ! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0) )
if (! CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0)) 

现在是这样的:
我要往里面写一个getinfo:


while (!end_write_pipe)
{
if (!write_message.empty())
{
bSuccess = WriteFile(g_hChildStd_IN_Wr, ( char* )write_message.c_str(), write_message.length(), &dwWritten, &o);
}
else
{
Sleep(100);
}
}


然后从另一handle中取出消息,注意这里,需要两次ReadFile才能出现结果,一次什么都读不到:

while (!end_read_pipe)
{
bSuccess = ReadFile( g_hChildStd_OUT_Rd, chBuf, 90, &dwRead, &o);
DWORD dwError = GetLastError();
if (!bSuccess && (dwError == ERROR_IO_PENDING))
{
WaitForSingleObject(g_hChildStd_OUT_Rd, INFINITE);
bSuccess = true;
}
if (bSuccess && write_message == "$gw")
{
int i = strlen(chBuf);
char str[10] = {'\0'};
memcpy(str, chBuf+2, 3);
w = atoi(str);
char str2[10] = {'\0'};
memcpy(str2, chBuf+6, 3);
h = atoi(str2);
if( ! bSuccess || dwRead == 0 ) break;
if (w == (int)time_total_ms)
{
ReadFile( g_hChildStd_OUT_Rd, chBuf, 90, &dwRead, NULL);
int i = strlen(chBuf);
char str[10] = {'\0'};
memcpy(str, chBuf+2, 3);
w = atoi(str);
char str2[10] = {'\0'};
memcpy(str2, chBuf+6, 3);
h = atoi(str2);
if( ! bSuccess || dwRead == 0 ) break; 
}
write_message.clear();
printf("width : %d, height : %d\n", w, h);
}
else if (bSuccess && write_message == "$gt")
{
int i = strlen(chBuf);
char str[10] = {'\0'};
memcpy(str, chBuf+2, i - 2);
time_total_ms = atof(str);
if (w == (int)time_total_ms)
{
ReadFile( g_hChildStd_OUT_Rd, chBuf, 90, &dwRead, NULL);
int i = strlen(chBuf);
char str[10] = {'\0'};
memcpy(str, chBuf+2, i - 2);
time_total_ms = atof(str);
}
write_message.clear();
printf("time_total_ms is : %f\n", time_total_ms);
}
else
{
Sleep(100);
}
memset(chBuf, 0, strlen(chBuf));
}


但是ffplay还接收q和p信息,q为退出,p为暂停和播放,上面的代码,会导致输入p的时候,造成无数次的暂停和播放(也就是反复的写入p)!

注意这里,我觉得更奇葩的是,
把Write改成这样的:

while (!end_write_pipe)


{
if (!write_message.empty())
{
printf("i : %d\n", ++i);
bSuccess = WriteFile(g_hChildStd_IN_Wr, ( char* )write_message.c_str(), write_message.length(), &dwWritten, &o);
}
else
{
Sleep(100);
}
}



ReadFile这样的:

while (!end_read_pipe)
{
bSuccess = ReadFile( g_hChildStd_OUT_Rd, chBuf, 90, &dwRead, &o);
DWORD dwError = GetLastError();
if (!bSuccess && (dwError == ERROR_IO_PENDING))
{
WaitForSingleObject(g_hChildStd_OUT_Rd, INFINITE);
bSuccess = true;
}
if (bSuccess && write_message == "$gw")
{
int i = strlen(chBuf);
char str[10] = {'\0'};
memcpy(str, chBuf+2, 3);
w = atoi(str);
char str2[10] = {'\0'};
memcpy(str2, chBuf+6, 3);
h = atoi(str2);
if( ! bSuccess || dwRead == 0 ) break;
// if (w == (int)time_total_ms)
// {
// ReadFile( g_hChildStd_OUT_Rd, chBuf, 90, &dwRead, NULL);
// int i = strlen(chBuf);
// char str[10] = {'\0'};
// memcpy(str, chBuf+2, 3);
// w = atoi(str);
// char str2[10] = {'\0'};
// memcpy(str2, chBuf+6, 3);
// h = atoi(str2);
// if( ! bSuccess || dwRead == 0 ) break; 
// }
write_message.clear();
printf("width : %d, height : %d\n", w, h);
}
else if (bSuccess && write_message == "$gt")
{
int i = strlen(chBuf);
char str[10] = {'\0'};
memcpy(str, chBuf+2, i - 2);
time_total_ms = atof(str);
// if (w == (int)time_total_ms)
// {
// ReadFile( g_hChildStd_OUT_Rd, chBuf, 90, &dwRead, NULL);
// int i = strlen(chBuf);
// char str[10] = {'\0'};
// memcpy(str, chBuf+2, i - 2);
// time_total_ms = atof(str);
// }
write_message.clear();
printf("time_total_ms is : %f\n", time_total_ms);
}
else
{
Sleep(100);
}
memset(chBuf, 0, strlen(chBuf));
}

输出34次i,就不必两次ReadFile了!(如果像上面的代码不读两次 比如第一次获取wh,接着获取time,会出现time的结果是w的value!)

还有一种情况WriteFile的代码:

while (!end_write_pipe)
{
if (!write_message.empty())
{
write_message += "\r\n";
bSuccess = WriteFile(g_hChildStd_IN_Wr, ( char* )write_message.c_str(), write_message.length(), &dwWritten, &o);
//DWORD dwError = GetLastError();
write_message.clear();
}
else
{
Sleep(100);
}
}


p和q正常,但是永远获取不到wh和time!

这是很奇葩的!所以来这边问问!谢谢各位帮我看看,我可能写了一天代码了,一些细节问题没有注意到! CreatePipe WriteFile ReadFile

STARTUPINFO? createprocess
[解决办法]
你可以下载这个参考参考,http://download.csdn.net/detail/xiaohuh421/2682969 VC++实现CMD命令执行与获得返回信息
[解决办法]

引用:
引用:
引用:引用:
你用同步方式试试,我觉得是你异步ReadFile出问题了
我感觉我现在就是同步的!

你用了OverLapped,哪儿是同步啊?同步读写的话,最后一个参数应该是NULL
那我改成NULL也是一样的,我总觉得我的消息没控制好,从ReadFile那给我返回了多个……


比如应该是640&380的,却给我返回了640&380640&380640&380……
这个是正常的,已经说过了,面向流的,本来就是这样。你要自己分包处理,加标记、加每个包长度标识、自己做缓存来黏包
[解决办法]
引用:
引用:引用:引用:
引用:引用:
你用同步方式试试,我觉得是你异步ReadFile出问题了
我感觉我现在就是同步的!

你用了OverLapped,哪儿是同步啊?同步读写的话,最后一……

你的这种情况就是黏包

热点排行