创建文件视图的进程:int main()
{
HANDLE hFileMap=CreateFileMapping((HANDLE)-1,NULL,PAGE_READWRITE,0,sizeof(DWORD),_T("hello")); if(hFileMap==INVALID_HANDLE_VALUE)
{
if(ERROR_ALREADY_EXISTS!=GetLastError())
{
printf("创建文件映射内存内核对象失败\n");
return -1;
}
hFileMap=OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,_T("hello"));
if(hFileMap==NULL)
{
printf("打开文件视图错误\n");
return -1;
}
}
DWORD* pData=(DWORD*)MapViewOfFile(hFileMap,FILE_MAP_ALL_ACCESS,0,0,0);
if(pData==NULL)
{
printf("映射文件失败\n");
return -1;
}
*pData=::GetCurrentThreadId(); CloseHandle(hFileMap);
getchar();
return 0;}
另一个进程:
int main()
{ HANDLE hMapFile=OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,_T("hello"));
if(hMapFile==NULL)
{
printf("打开文件视图错误,错误码为:%d\n",GetLastError()); //错误码是2 ?????
return -1;
} LPVOID pData=MapViewOfFile(hMapFile,FILE_MAP_ALL_ACCESS,0,0,sizeof(DWORD)); if(pData!=NULL)
printf("%s\n",(char*)pData); CloseHandle(hMapFile); getchar(); return 0;}
{
HANDLE hFileMap=CreateFileMapping((HANDLE)-1,NULL,PAGE_READWRITE,0,sizeof(DWORD),_T("hello")); if(hFileMap==INVALID_HANDLE_VALUE)
{
if(ERROR_ALREADY_EXISTS!=GetLastError())
{
printf("创建文件映射内存内核对象失败\n");
return -1;
}
hFileMap=OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,_T("hello"));
if(hFileMap==NULL)
{
printf("打开文件视图错误\n");
return -1;
}
}
DWORD* pData=(DWORD*)MapViewOfFile(hFileMap,FILE_MAP_ALL_ACCESS,0,0,0);
if(pData==NULL)
{
printf("映射文件失败\n");
return -1;
}
*pData=::GetCurrentThreadId(); CloseHandle(hFileMap);
getchar();
return 0;}
另一个进程:
int main()
{ HANDLE hMapFile=OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,_T("hello"));
if(hMapFile==NULL)
{
printf("打开文件视图错误,错误码为:%d\n",GetLastError()); //错误码是2 ?????
return -1;
} LPVOID pData=MapViewOfFile(hMapFile,FILE_MAP_ALL_ACCESS,0,0,sizeof(DWORD)); if(pData!=NULL)
printf("%s\n",(char*)pData); CloseHandle(hMapFile); getchar(); return 0;}
解决方案 »
- 模式对话框vs非模式对话框
- 求助:Visual Studio .NET 2003环境变量设置
- Invalid allocation size - 922a9aa8 (exceeded 7ffdefff)
- 问熟悉的大虾:List Control控件中的内容能编辑吗?
- 关于CByteArray的一点疑惑???
- 求教高手,监视一段时间内计算机所有的注册表信息和文件信息的变动情况?
- 如何得到当前进程的进程句柄?
- 要显示QQ上用户的信息,就像QQ中的一个“查看用户信息”对话框,我想做成和它一模一样的,那个对话框外形我可以做成一样的,可是其中要显
- 关于多文件全局变量的问题
- 是牛人的进来看
- 如何生成动静态库
- 查找USB的方法,寻求思路
问题当你运行第一个程序的时候,在运行第二个程序的时候
你第一个程序的共享内存已经被你关闭了
HANDLE hFileMap=CreateFileMapping((HANDLE)-1,NULL,PAGE_READWRITE,0,sizeof(DWORD),_T("hello")); if(hFileMap==INVALID_HANDLE_VALUE)
{
if(ERROR_ALREADY_EXISTS!=GetLastError())
{
printf("创建文件映射内存内核对象失败\n");
return -1;
}
hFileMap=OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,_T("hello"));
if(hFileMap==NULL)
{
printf("打开文件视图错误\n");
return -1;
}
}
DWORD* pData=(DWORD*)MapViewOfFile(hFileMap,FILE_MAP_ALL_ACCESS,0,0,0);
if(pData==NULL)
{
printf("映射文件失败\n");
return -1;
}
*pData=::GetCurrentThreadId();
getchar();
CloseHandle(hFileMap);
1. 这个例子与我以前的一个帖子有一点的共性:
那个例子是子进程继承了父进程的一个句柄(父进程中创建了一个event),我在父和子都调用了CloseHandle(事件)毫无问题2.现在说我对的答案的疑问:两个进程使用 内存共享机制,那么这个内核对象,何时消失,回收?
当引用计数为0的时候!!这个没争议吧。第二个进程 打开这个句柄后,那么引用计数+1,没争议吧。
好了,CloseHandle(hFileMap);
getchar();只会导致该句柄无效,且减少次数! 如果没有第二个进程的话,那么引用计数为0了。系统何时回收,似乎没有规定。这个不是重点需要关注的。当 第二个进程打开后,引用计数为2了。 因为+1导致的。
所以,。似乎你说的没占到道理啊
ERROR_FILE_NOT_FOUND
2 (0x2)
The system cannot find the file specified.
于是如果是权限问题,将返回的不是2。所以LZ最好实验一下,看看执行到哪步时那个共享内存没了。
{
HANDLE hFileMap=CreateFileMapping((HANDLE)-1,NULL,PAGE_READWRITE,0,sizeof(DWORD),_T("hello")); if(hFileMap==INVALID_HANDLE_VALUE)
{
if(ERROR_ALREADY_EXISTS!=GetLastError())
{
printf("创建文件映射内存内核对象失败\n");
return -1;
}
hFileMap=OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,_T("hello"));
if(hFileMap==NULL)
{
printf("打开文件视图错误\n");
return -1;
}
}
DWORD* pData=(DWORD*)MapViewOfFile(hFileMap,FILE_MAP_ALL_ACCESS,0,0,0);
if(pData==NULL)
{
printf("映射文件失败\n");
return -1;
}
*pData=::GetCurrentThreadId();
printf("当前线程的id为:%d\n",*pData); getchar();
CloseHandle(hFileMap);
return 0;}int main()
{ HANDLE hMapFile=OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,_T("hello"));
if(hMapFile==NULL)
{
printf("打开文件视图错误,错误码为:%d\n",GetLastError());
return -1;
} LPVOID pData=MapViewOfFile(hMapFile,FILE_MAP_ALL_ACCESS,0,0,sizeof(DWORD)); if(pData!=NULL)
printf("%d\n",(DWORD*)pData);
else
printf("映射的时候错误,错误码为:%d", GetLastError()); CloseHandle(hMapFile); getchar(); return 0;}
if(pData!=NULL)
printf("%d\n", *(DWORD*)pData);
发现用打不开说明:内核对象这种东西, 很可能进程结束,操作系统就回收了。反过来再做实验:进程1用getchar保持着不接受, 进程2先接受,那么用楼上说的工具依然可以看到这个句柄
似乎一般的代码是无法做到获得 引用计数是多少?
还有在代码中 Closehandle 似乎只是一个好习惯,但不是必然要加的,操作系统当进程结束后,似乎就会及时回收。
但是我做了实验发现后: 对于文件视图(内存共享方式锁产生的这种内核对象),当CloseHandle后,立即消失。对于 事件内核对象也是如此。以上说的有个前提:必须把内核对象命名,否则工具看不到。
但是:虽然工具看不到,不能够说明 就消失了,因为无名的内核对象也是看不到的(用工具)
///////////////////////////////////////////////////////////////////////////////////进程1创建一个内核对象,进程2使用之。 目前的实验,似乎可以得出一个结论:进程1不能够CloseHandle另外:进程2打开之前,必须保证进程1不结束。
回答 引用计数的疑问:似乎是在进程2打开时候,必须保证该内核对象的引用计数为1以上,否则一旦为0,那那么狠可能打开失败。
int main()
{
HANDLE hFileMap=CreateFileMapping((HANDLE)-1,NULL,PAGE_READWRITE,0,sizeof(DWORD),_T("hello")); if(hFileMap==INVALID_HANDLE_VALUE)
{
if(ERROR_ALREADY_EXISTS!=GetLastError())
{
printf("创建文件映射内存内核对象失败\n");
return -1;
}
hFileMap=OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,_T("hello"));
if(hFileMap==NULL)
{
printf("打开文件视图错误\n");
return -1;
}
}
DWORD* pData=(DWORD*)MapViewOfFile(hFileMap,FILE_MAP_ALL_ACCESS,0,0,0); if(pData==NULL)
{
printf("映射文件失败\n");
return -1;
}
*pData=::GetCurrentThreadId();
// 创建一个命名事件,用于通知对方:我写完了,你可以读取了
HANDLE hWriteReadyEvent = CreateEvent(NULL, FALSE, FALSE, "GWriteReadyEvent");
if ( NULL != hWriteReadyEvent ) {
// 这儿喊了一声
SetEvent(hWriteReadyEvent );
}
// 创建一个命名事件,用于等待对方告诉我:他读完了,你可以继续你的工作了
HANDLE hReadReadyEvent = CreateEvent(NULL, FALSE, FALSE, "GReadReadyEvent");
if ( NULL != hReadReadyEvent ) {
// 无限期等
DWORD dwWaitReson = WaitforSingleObject( hReadReadyEvent, INFINITE);
if ( WAIT_OBJECT_0 == dwWaitReson ) {
// 等成功了
}
else {
// 等失败了
}
}
// 这个你忘记加了
UnmapViewOfFile(hFileMap);
// 可以放心关了
CloseHandle(hFileMap);
hFileMap = NULL;
return 0;}另一个进程:C/C++ codeint main()
{
// 打开(可能是创建)那个命名事件
HANDLE hWriteReadyEvent = CreateEvent(NULL, FALSE, FALSE, "GWriteReadyEvent");
if ( NULL != hWriteReadyEvent ) {
// 无限等那个事件
DWORD dwWaitReson = WaitforSingleObject( hReadReadyEvent, INFINITE);
if ( WAIT_OBJECT == dwWaitReson ) {
// 成功等到了,可以读了
}
else {
// 等失败了,就不管了
return -1;
}
}
HANDLE hMapFile=OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,_T("hello"));
if(hMapFile==NULL)
{
printf("打开文件视图错误,错误码为:%d\n",GetLastError()); //错误码是2 ?????
return -1;
} LPVOID pData=MapViewOfFile(hMapFile,FILE_MAP_ALL_ACCESS,0,0,sizeof(DWORD)); if(pData!=NULL)
printf("%s\n",(char*)pData);
// 这个你忘记加了
UnmapViewOfFile(hFileMap);
CloseHandle(hFileMap);
hFileMap = NULL;
HANDLE hReadReadyEvent = CreateEvent(NULL, FALSE, FALSE, "GReadReadyEvent");
if ( NULL != hReadReadyEvent ) {
// 通知对方我读完了,你想干嘛就干嘛吧
SetEvent(hReadReadyEvent );
} return 0;}
没调试过,大概就是这个意思。