我有两个用C语言编写的窗体应用程序,一个包含一个由两个整数组成的结构,另一个将使用CreateFileMapping接收它。
虽然没有直接关系,但我希望有三个事件,所以每个进程可以互相“说话”,一个说第一个程序有东西要传递到第二个,一个说第一个已关闭,另一个说第二个已关闭。
这样做最好的方法是什么?我已经查看了CreateFileMapping操作的MSDN条目,但我仍然不确定应该如何完成。
我不想在没有清楚了解我需要做什么的情况下开始实施它。
感谢您的时间。
答案 0 :(得分:4)
文件映射似乎不是处理此问题的最佳方法。只需在一个方向上发送两个整数就有 lot 的开销。对于类似的东西,我会考虑像管子一样的东西。管道自动化大多数其他细节,因此(例如)尝试读取或写入另一端已关闭的管道将失败,GetLastError()
将返回ERROR_BROKEN_PIPE
。要获得相当于第三个事件(说有等待的东西),你可以在重叠模式下使用管道。您可以等待管道句柄本身(请参阅文档中的警告)或使用OVERLAPPED
结构,其中包含事件句柄。
答案 1 :(得分:2)
如果您想使用共享内存,在回答您将如何执行此操作的问题时,可以使用共享内存中的一个字节在两个进程之间进行通信。这是一些示例代码。您可以使用信号量轻松替换等待循环
/
/ SharedMemoryServer.cpp : Defines the entry point for the console application.
//
//#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <conio.h> // getch()
#include <tchar.h>
#include "Aclapi.h" // SE_KERNEL_OBJECT
#define SM_NAME "Global\\SharedMemTest"
#define SIGNAL_NONE 0
#define SIGNAL_WANT_DATA 1
#define SIGNAL_DATA_READY 2
#define BUFF_SIZE 1920*1200*4
struct MySharedData
{
unsigned char Flag;
unsigned char Buff[BUFF_SIZE];
};
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hFileMapping = CreateFileMapping (INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_COMMIT, 0, sizeof(MySharedData), SM_NAME);
if (hFileMapping == NULL)
printf ("CreateFileMapping failed");
else
{
// Grant anyone access
SetNamedSecurityInfo(SM_NAME, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, 0, 0, (PACL) NULL, NULL);
MySharedData* pSharedData = (MySharedData *) MapViewOfFile(hFileMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
printf("Waiting for instructions\n");
while (pSharedData->Flag == SIGNAL_NONE) // Wait to be signaled for data
;
if (pSharedData->Flag == SIGNAL_WANT_DATA)
{
printf("Signal for data received\n");
size_t len = sizeof(pSharedData->Buff);
memset (pSharedData->Buff, 0xFF, len);
pSharedData->Flag = SIGNAL_DATA_READY;
printf("Data ready signal set\n");
// Wait for data to be consumed or up to 10 seconds
while (pSharedData->Flag != SIGNAL_NONE)
;
printf("Data consumed signal detected\n");
}
}
_getch();
return 0;
}
客户端进程是等效的,但是在调用MapViewOfFile()之后的else情况下的代码看起来像这样:
pSharedData->Flag = SIGNAL_WANT_DATA; // Signal for data
printf("Signal for data set\n");
while (pSharedData->Flag != SIGNAL_DATA_READY)
;
printf("Data ready signal detected\n");
if (pSharedData->Flag == SIGNAL_DATA_READY)
{
// Dump the first 10 bytes
printf ("Data received: %x %x %x %x %x %x %x %x %x %x\n",
pSharedData->Buff[0], pSharedData->Buff[1], pSharedData->Buff[2],
pSharedData->Buff[3], pSharedData->Buff[4], pSharedData->Buff[5],
pSharedData->Buff[6], pSharedData->Buff[7], pSharedData->Buff[8],
pSharedData->Buff[9]);
}
答案 2 :(得分:0)
您可以使用CreateSemaphore并为最后一个参数提供名称以创建命名信号量。进程可以共享该信号量(另一个进程将使用OpenSemaphore)。一个过程在数据准备就绪时发出信号,另一个过程可以等待数据。
说完这个之后,我不得不同意Jerry的说法,使用烟斗可能会让它变得更加简单。另一方面,如果需要移植信号量(或事件),则可以使用带有信号量(或事件)的共享内存方法更简单地转换到其他平台(例如Linux)。