通过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()函数连接到它们吗?

iCMS 回答:通过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循环中询问用户输入,以及是否可以不使用互斥锁。

本文链接:https://www.f2er.com/1668350.html

大家都在问