📜  使用Windows线程的C ++ File Writer-Reader应用程序(1)

📅  最后修改于: 2023-12-03 15:36:37.593000             🧑  作者: Mango

使用Windows线程的C ++ File Writer-Reader应用程序介绍

简介

本文介绍了一种使用Windows线程的C ++ 文件写入器-阅读器应用程序,该程序使用Windows API提供的线程函数来实现并发文件读取和写入。

实现原理

该程序由两个线程组成:写入线程和读取线程。

写入线程将文本写入指定的文件,并在文本写入期间阻塞读取线程,以确保数据的完整性。

读线程读取文件中的文本,并在读取期间阻塞写线程以防止数据损坏。

通过使用Windows API提供的线程函数,可以对这两个线程执行并发操作。

代码实现

写入器线程:

DWORD WINAPI WriterThread(LPVOID lpParam) {
    DWORD dwBytesWritten;
    HANDLE hFile;

    WriterThreadParams* params = (WriterThreadParams*)lpParam;
    LPCTSTR fileName = params->FileName;
    LPCTSTR textToWrite = params->TextToWrite;

    hFile = CreateFile(fileName, // filename
        GENERIC_WRITE, // file access
        0, // no sharing
        NULL, // default security
        CREATE_ALWAYS, // always create new file
        FILE_ATTRIBUTE_NORMAL, // normal file attributes
        NULL); // no template file

    if (hFile == INVALID_HANDLE_VALUE) {
        return GetLastError();
    }

    WriteFile(hFile, // handle to file
        textToWrite, // data buffer
        lstrlen(textToWrite), // number of bytes to write
        &dwBytesWritten, // number of bytes written
        NULL); // overlapped buffer

    CloseHandle(hFile);

    return 0;
}

阅读器线程:

DWORD WINAPI ReaderThread(LPVOID lpParam) {
    DWORD dwBytesRead;
    HANDLE hFile;

    ReaderThreadParams* params = (ReaderThreadParams*)lpParam;
    LPCTSTR fileName = params->FileName;
    LPTSTR buffer = params->Buffer;
    DWORD bufferSize = params->BufferSize;

    hFile = CreateFile(fileName,
        GENERIC_READ,
        0,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL);

    if (hFile == INVALID_HANDLE_VALUE) {
        return GetLastError();
    }

    ReadFile(hFile,
        buffer,
        bufferSize - 1, // leave room for null terminator
        &dwBytesRead,
        NULL);

    CloseHandle(hFile);
    buffer[dwBytesRead] = '\0'; // null-terminate buffer

    return 0;
}

两个线程的参数结构定义:

typedef struct {
    LPCTSTR FileName;
    LPCTSTR TextToWrite;
} WriterThreadParams;

typedef struct {
    LPCTSTR FileName;
    LPTSTR Buffer;
    DWORD BufferSize;
} ReaderThreadParams;
使用示例

下面是使用这些函数的示例:

void TestFileWriterReader() {
    HANDLE writerThread, readerThread;
    DWORD writerThreadID, readerThreadID;
    DWORD waitResult;

    TCHAR buffer[256] = { 0 };

    WriterThreadParams writerThreadParams = {
        _T("test.txt"),
        _T("Hello world!")
    };
    ReaderThreadParams readerThreadParams = {
        _T("test.txt"),
        buffer,
        sizeof(buffer) / sizeof(buffer[0])
    };

    writerThread = CreateThread(NULL, 0, WriterThread, &writerThreadParams, 0, &writerThreadID);
    readerThread = CreateThread(NULL, 0, ReaderThread, &readerThreadParams, 0, &readerThreadID);

    waitResult = WaitForMultipleObjects(2, // number of handles
        new HANDLE[]{writerThread, readerThread}, // handles to wait on
        TRUE, // wait for all
        INFINITE); // wait forever

    if (waitResult == WAIT_OBJECT_0) {
        _tprintf(_T("File write succeeded\n"));
        _tprintf(_T("%s\n"), buffer);
    }
    else if (waitResult == WAIT_OBJECT_0 + 1) {
        _tprintf(_T("File read succeeded\n"));
        _tprintf(_T("%s\n"), buffer);
    }
    else {
        _tprintf(_T("Wait failed: %d\n"), GetLastError());
    }

    CloseHandle(writerThread);
    CloseHandle(readerThread);
}
结论

使用Windows API提供的线程函数可以实现并发文件读取和写入。使用此方法可增强应用程序的性能和效率。但是,这种方法也可能会引发文件竞争的问题,应当谨慎使用。