现在已经困扰了我好几个小时,我无法解决这个问题。
到目前为止,我的编码没有太多问题。我的任务是通过循环文件从一个进程发送消息到另一个进程。消息由第一个进程中的线程生成,通过共享内存发送到此进程中的另一个线程,然后线程将此消息发送到分离的进程。我能够创建子进程并向它发送一些消息,但是当我开始实现信号量来制作循环文件时,事情就变成了南方。
代码很重,虽然我使用的是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 created\n";
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 Status\n";
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 TP\debug.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: %d\n", GetLastError());
pEventSent= OpenEvent(EVENT_ALL_ACCESS, FALSE, (LPCWSTR) "SentMSG");
check(pEventSent, "Impossivel abrir evento SentMSG: %d\n", GetLastError());
// Cria evento com reset automático
pEventRead= OpenEvent(EVENT_ALL_ACCESS, FALSE, (LPCWSTR) "RecievedMSG");
check(pEventRead, "Impossivel abrir evento RecievedMSG: %d\n", 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= %s\n", 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.这是什么意思o尝试OpenEvent并得到错误号2?
我坚信这个问题依赖于MapViewOfFile,因为我读过某个地方,如果你没有得到正确的偏移量和文件大小(关于粒度和文件不是0大小的东西,我只是无法理解)。也许有一大块记忆被过度重视并弄乱了我的程序。
Check是一个宏,是Zed的Awesome Debug宏的修改版本:http://c.learncodethehardway.org/book/ex20.html
答案 0 :(得分:0)
对于对发生的事情感到好奇的人,我试图通过si.dwFlags
创建一个新的控制台。但是,MSDN未定义位设置si.dwFlags = CREATE_NEW_CONSOLE;
,因此它不是有效配置。我的猜测是它弄乱了一些关于IPC内存访问的相关寄存器,因此通过文件映射搞乱了句柄的打开和共享内存的实际使用。
正确的应用是在CREATE_NEW_CONSOLE
内设置CreateProcess
,就像它最初发布时一样:
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
。