CreateProcess和MapViewOfFile有很多问题
Lots of trouble with CreateProcess and MapViewOfFile
它已经困扰我好几个小时了,我无法解决这个问题。
到目前为止,我一直在编码,没有遇到太多问题。我的任务是通过循环文件将消息从一个进程发送到另一个进程。消息由第一个进程中的一个线程生成,通过共享内存发送到该进程中的另一个线程,然后该线程将此消息发送到分离的进程。我能够创建子进程并向它发送一些消息,但当我开始实现信号量以生成循环文件时,事情就发生了问题。
代码很重,虽然我使用的是c++,但它是结构化的,所以有点难以理解,也有点混乱。一旦我做对了,我就会开始清理。
这是进程1:的线程a
DWORD WINAPI StRetFunc(LPVOID id)
{
LONG LPrevCount;
HANDLE pFile;
HANDLE pSent;
HANDLE pRecieved;
char* pImage;
BOOL endThread = false;
unsigned int pPos=0;
BOOL bStatus;
STARTUPINFO si; // StartUpInformation for new process
PROCESS_INFORMATION NewProcess; // New Process infos
pFile = CreateFileMapping(
(HANDLE)0xFFFFFFFF,
NULL,
PAGE_READWRITE, // access type
0, // dwMaximumSizeHigh
BYTE_TAM_ARQ, // dwMaximumSizeLow
(LPCWSTR) "CircFile"); // name
check(pFile, "Cannot open file.");
pSent = CreateEvent(NULL, TRUE, FALSE, (LPCWSTR) "SentMSG");
check(pSent, "Cannot create event SentMSG (pSent).");
pRecieved = CreateEvent(NULL, TRUE, FALSE, (LPCWSTR) "RecievedMSG");
check(pRecieved, "Cannot create event RecievedMSG (pRecieved)");
cout << "Handles createdn";
LPWSTR szCmdline = _tcsdup(TEXT("..\Debug\ATR TP - LS.exe"));
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si); // Tamanho da estrutura em bytes
si.dwFlags = CREATE_NEW_CONSOLE;
bStatus = CreateProcess(
szCmdline , // Nome
NULL, // linha de comando
NULL, // atributos de segurança: Processo
NULL, // atributos de segurança: Thread
FALSE, // herança de handles
CREATE_NEW_CONSOLE, // CreationFlags
//NORMAL_PRIORITY_CLASS,
NULL, // lpEnvironment
NULL, // diretório corrente do filho
&si, // lpStartUpInfo
&NewProcess); // lpProcessInformation
check(bStatus, "Impossivel criar processo: %s", DecodeError());
while(WaitForSingleObject(hEvent_Esc, 0) != WAIT_OBJECT_0) {
CheckFreezeEvent(stretEvent, "Retira Status");
WaitForSingleObject(stretSemaphore, INFINITE);
{
do {
while(circ_mem[stret_index].empty() == true)
++stret_index %= MAX_LISTA_CIRC;
while(memrdy[stret_index] == false);
if(circ_mem[stret_index].substr(7, 3) == "000")
break;
else
++stret_index %= MAX_LISTA_CIRC;
if(WaitForSingleObject(hEvent_Esc, 0) == WAIT_OBJECT_0) {
endThread = true;
break;
}
if(WaitForSingleObject(stretEvent, 0) != WAIT_OBJECT_0)
CheckFreezeEvent(stretEvent, "Retira Status");
} while(true);
if(endThread) break;
CheckFreezeEvent(stretEvent, "Retira Status");
cout << "Status Retirado: " << circ_mem[stret_index] << " Na posicao: " << stret_index << "n";
//WriteToFile
pImage = (char*) MapViewOfFile(
pFile,
FILE_MAP_WRITE,
0,
0,
35);
strcpy(pImage, circ_mem[stret_index].c_str());
SetEvent(pSent);
while(WaitForSingleObject(pRecieved, 0) != WAIT_OBJECT_0 ) {
if(WaitForSingleObject(hEvent_Esc, 0)) break;
}
ResetEvent(pRecieved);
circ_mem[stret_index].clear();
memrdy[stret_index] = false;
ReleaseSemaphore(iSemaphore, 1, &LPrevCount);
}
}
cout << "Encerrando Thread Retirada Statusn";
CloseHandle(pFile);
CloseHandle(pSent);
CloseHandle(pRecieved);
return(0);
}
这是子进程
// ATR TP - LS.cpp : Defines the entry point for the console application.
//
#include "FileFuncs.h"
#include "..ATR TPdebug.h"
int main(int argc, char* argv[])
{
BOOL bStatus;
char *lpImage; // Apontador para imagem local
HANDLE pFile;
HANDLE pEventSent;
HANDLE pEventRead;
HANDLE hEsc;
pFile= OpenFileMapping(
FILE_MAP_ALL_ACCESS,
FALSE, // Handle herdável
(LPCWSTR) "CircFile"); // Escolha o seu nome preferido
check(pFile, "Nao foi possivel abrir file mapping: %s", DecodeError());
lpImage= (char *)MapViewOfFile(
pFile,
FILE_MAP_WRITE, // Direitos de acesso: leitura e escrita
0, // dwOffsetHigh
0, // dwOffset Low
BYTE_TAM_ARQ); // Número de bytes a serem mapeados
check(lpImage, "Impossivel criar map view.");
// Abre eventos criados
hEsc = OpenEvent(EVENT_ALL_ACCESS, FALSE, (LPCWSTR) "myEsc");
check(hEsc, "Impossivel abrir evento ESC: %dn", GetLastError());
pEventSent= OpenEvent(EVENT_ALL_ACCESS, FALSE, (LPCWSTR) "SentMSG");
check(pEventSent, "Impossivel abrir evento SentMSG: %dn", GetLastError());
// Cria evento com reset automático
pEventRead= OpenEvent(EVENT_ALL_ACCESS, FALSE, (LPCWSTR) "RecievedMSG");
check(pEventRead, "Impossivel abrir evento RecievedMSG: %dn", GetLastError());
cout << "[Exibicao] Handles Abertos" << endl;
bool endProg = false;
while(WaitForSingleObject(hEsc, 0) != WAIT_OBJECT_0) {
// Espera que processo A escreva mensagem
while(WaitForSingleObject(pEventSent, 0) != WAIT_OBJECT_0) {
if(WaitForSingleObject(hEsc, 0) == WAIT_OBJECT_0) endProg = true;
}
if(endProg) break;
ResetEvent(pEventSent);
if (strcmp(lpImage, "")==0) break;
printf("[Exibicao] Mensagem Status Recebida= %sn", lpImage);
// Limpa memória compartilhada
strcpy(lpImage, "");
SetEvent(pEventRead); // Avisa processo A
}
// Elimina mapeamento
CloseHandle(pFile);
CloseHandle(pEventSent);
CloseHandle(pEventRead);
bStatus=UnmapViewOfFile(lpImage);
check(bStatus, "Unmap Falhou.");
//cout << "Encerrando Processo Retirada Status ARQUIVO" << endl;
// ^if i uncomment this line, hell breaks loose
ExitProcess(0);
return EXIT_SUCCESS;
return 0;
}
如果我取消注释上一个文件中包含cout的最后一行,我就无法打开我的事件,也无法对子进程执行任何操作。cout与我的活动开幕有什么关系?
此外,在我检查错误后,GetLastError()会给我数字2。尝试OpenEvent并得到错误号2意味着什么?
我坚信这个问题依赖于MapViewOfFile,因为我在某个地方读到过,如果偏移量和文件大小不正确(关于粒度和文件大小不是0的问题,我就是无法理解)。也许有一大块内存被占用了,打乱了我的程序。
Check是一个宏,是Zed的Awesome Debug宏的修改版本:http://c.learncodethehardway.org/book/ex20.html
对于任何好奇发生了什么的人来说,我试图通过si.dwFlags
创建一个新的控制台。但是,位设置si.dwFlags = CREATE_NEW_CONSOLE;
不是由MSDN定义的,因此它不是一个有效的配置。我的猜测是,它扰乱了一些与IPC内存访问相关的寄存器,从而扰乱了句柄的打开和通过文件映射共享内存的实际使用。
正确的做法是在CreateProcess
中设置CREATE_NEW_CONSOLE
,就像最初发布的那样:
bStatus = CreateProcess(
szCmdline , // Nome
NULL, // linha de comando
NULL, // atributos de segurança: Processo
NULL, // atributos de segurança: Thread
FALSE, // herança de handles
CREATE_NEW_CONSOLE, // CreationFlags
//NORMAL_PRIORITY_CLASS,
NULL, // lpEnvironment
NULL, // diretório corrente do filho
&si, // lpStartUpInfo
&NewProcess); // lpProcessInformation
check(bStatus, "Impossivel criar processo: %s", DecodeError());
如果您不确定如何使用dwFlags
,请避免使用。
- 警告处理为错误这里有什么问题
- 最小硬币更换问题(自上而下方法)
- 为"adjacent"变量赋值时出现问题
- 我的神经网络不起作用 [XOR 问题]
- 在Ubuntu 16.04上安装Cilk时出现问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 编译包含字符串的代码时遇到问题
- Project Euler问题4的错误解决方案
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 静态数据成员的问题-修复链接错误会导致编译器错误
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 一个关于在C++中重载布尔运算符的问题
- 首要问题的答案让值班员搞错了
- setlocale的C++土耳其字符串问题
- 如何重构类层次结构以避免菱形问题
- 基于boost的程序的静态链接——zlib问题
- CreateProcess和MapViewOfFile有很多问题
- 使用CreateFileMapping和MapViewofFile共享内存的问题