如何解决通过CreateFile将文件用作互斥量
我被赋予创建2个流程的任务。第一个打开一个文件“ log.txt”,并将用户提供的输入添加到其中。 第二个过程旨在成为该文件的“监视器”。它检查它是否存在,给出其大小,并给出自第二个过程开始以来用户输入的字符数。我正在使用GetFileSize()函数,所以这不是问题。
我对CreateProcess()和CreateFile()函数有点困惑,因为我不确定如何将它们彼此连接。
我已阅读到可以通过更改其标志将CreateFile()函数用作互斥体。我想出了这样的东西:
HANDLE hFile = CreateFile(
"log.txt",FILE_APPEND_DATA,FILE_SHARE_WRITE | FILE_SHARE_READ,OPEN_ALWAYS,FILE_ATTRIBUTE_norMAL,0);
现在,我不确定如何将其连接到流程以及从何处启动流程。而且我也不知道自第二个过程开始以来如何检查给出的字符数。
有人可以向我解释何时启动这两个进程以及如何将CreateFile()函数连接到它们吗?
解决方法
FILE_SHARE_WRITE | FILE_SHARE_READ
将允许其他进程打开并共享读取和写入访问权限。您需要专门打开文件(使用dwShareMode = 0
),但这需要process2尝试以循环方式专门打开文件。
相反,使用CreateMutex
创建一个互斥锁,然后process1使用WaitForSingleObject
接收互斥锁,执行某些操作,然后执行ReleaseMutex
,process2使用WaitForSingleObject
等待释放的互斥锁,然后然后读取文件。 (一次同步完成)
过程2:
#include <windows.h>
#include <iostream>
int wmain(int argc,wchar_t* argv[])
{
HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS,false,L"MyMutex");
DWORD dwWaitResult = WaitForSingleObject(hMutex,INFINITE);
if (dwWaitResult == WAIT_OBJECT_0)
{
HANDLE hFile = CreateFile(L"log.txt",FILE_READ_ATTRIBUTES,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if (hFile == INVALID_HANDLE_VALUE)
{
std::cout << "CreateFile error " << GetLastError() << std::endl;
ReleaseMutex(hMutex);
}
else
{
DWORD size = GetFileSize(hFile,NULL);
std::cout << "File Size: " << size << std::endl;
CloseHandle(hFile);
ReleaseMutex(hMutex);
}
}
return 0;
}
过程1:
#include <windows.h>
#include <iostream>
int wmain(int argc,wchar_t* argv[])
{
HANDLE hMutex = CreateMutex(NULL,L"MyMutex");
DWORD dwWaitResult = WaitForSingleObject(hMutex,INFINITE);
if (dwWaitResult == WAIT_OBJECT_0)
{
STARTUPINFO si = { 0 };
si.cb = sizeof(si);
PROCESS_INFORMATION pi = { 0 };
CreateProcess(L"process2.exe",NULL,CREATE_NEW_CONSOLE,&si,&pi);
std::string buffer;
std::cin >> buffer;
HANDLE hFile = CreateFile(L"log.txt",FILE_APPEND_DATA,OPEN_ALWAYS,0);
DWORD written = 0;
WriteFile(hFile,buffer.c_str(),buffer.size(),&written,NULL);
CloseHandle(hFile);
ReleaseMutex(hMutex);
}
return 0;
}
但这比较麻烦,因为您每次都需要同步两个进程。
正如@Remy Lebeau所说,在process2中使用ReadDirectoryChangesW
:
#include <windows.h>
#include <iostream>
int wmain(int argc,wchar_t* argv[])
{
FILE_NOTIFY_INFORMATION* pInfo = NULL;
HANDLE hFile = CreateFile(L"Directory of log.txt",GENERIC_READ,FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,0);
while (1)
{
DWORD returned = 0;
DWORD dwOffset = 0;
BYTE szBuffer[1024] = { 0 };
ReadDirectoryChangesW(hFile,szBuffer,sizeof(szBuffer),FILE_NOTIFY_CHANGE_SIZE,&returned,NULL);
do
{
pInfo = (FILE_NOTIFY_INFORMATION*)&szBuffer[dwOffset];
if (wcscmp(pInfo->FileName,L"log.txt") == 0)
{
HANDLE hFile = CreateFile(L"path\\log.txt",0);
DWORD size = GetFileSize(hFile,NULL);
std::cout << "File Size: " << size << std::endl;
CloseHandle(hFile);
}
dwOffset += pInfo->NextEntryOffset;
} while (pInfo->NextEntryOffset != 0);
}
return 0;
}
进程1仅需要获得用户输入并写入文件:
#include <windows.h>
#include <iostream>
int wmain(int argc,wchar_t* argv[])
{
std::string buffer;
while (1)
{
std::cin >> buffer;
HANDLE hFile = CreateFile(L"log.txt",NULL);
CloseHandle(hFile);
}
return 0;
}
,
您似乎想要同步这两个过程,以便第二个过程等待第一个过程完成对“ log.txt”的写入。
为此,您需要在具有独占访问权(无FILE_SHARE_WRITE | FILE_SHARE_READ
)的第一个进程中打开该文件,并在完成写入后将其关闭。
第二个过程将尝试打开该文件,并且具有独占访问权限。如果第一个进程仍在使用该文件,则CreateFile()
将失败,并显示“拒绝访问”错误。这是mutex
的“互斥”概念的本质。然后,您将稍等片刻,然后重试。
与同步对象相反,我不知道等待文件可用的方式(对于互斥量,使用WaitForSingleObject
轻松完成)。
因此,我已经设法根据您的宝贵意见做出了一些贡献。我不确定这是否是解决此任务的正确方法。如果有人可以查看我的代码并给我一些其他提示,那就太好了。
这是我的代码
int main(int argc,char *argv[])
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si,sizeof(si));
ZeroMemory(&pi,sizeof(pi));
si.cb = sizeof(si);
CreateProcess("process2.exe",&pi);
std::string buffer;
std::cout << "Enter your text:" << std::endl;
getline(std::cin,buffer);
HANDLE hFile = CreateFile("log.txt",NULL);
hFile = CreateFile("log.txt",0);
if (hFile == INVALID_HANDLE_VALUE)
{
std::cout << "CreateFile error " << GetLastError() << std::endl;
}
else
{
DWORD size = GetFileSize(hFile,NULL);
std::cout << "\nCurrent file size: " << size << std::endl;
CloseHandle(hFile);
}
int stringLenght = 0;
for(int i=0; buffer[i]; i++)
stringLenght++;
std::cout << "\nCharacters given since last startup: " << stringLenght << std::endl;
return 0;
}
我不确定这是否是此任务的重点,还是应该检查文件大小并在while循环中询问用户输入,以及是否可以不使用互斥锁。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。