⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 readwrit.c

📁 侯捷先生翻译的书籍《Win32多线程程序设计》的源代码。
💻 C
字号:
/*
 * ReadWrit.c
 *
 * Sample code for "Multithreading Applications in Win32"
 * This is from Chapter 7, various listings.
 *
 * Demonstrates an implementation of the
 * Readers/Writers algorithm. This version
 * gives preference to readers.
 */

#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "ReadWrit.h"

// If we wait more than 2 seconds, then something is probably wrong!
#define MAXIMUM_TIMEOUT 2000

// Here's the pseudocode for what is going on:
//
// Lock for Reader:
//  Lock the mutex
//  Bump the count of readers
//  If this is the first reader, lock the data
//  Release the mutex
//
// Unlock for Reader:
//  Lock the mutex
//  Decrement the count of readers
//  If this is the last reader, unlock the data
//  Release the mutex
//
// Lock for Writer:
//  Lock the data
//
// Unlock for Reader:
//  Unlock the data

///////////////////////////////////////////////////////

BOOL MyWaitForSingleObject(HANDLE hObject)
{
    DWORD result;

    result = WaitForSingleObject(hObject, MAXIMUM_TIMEOUT);
    // Comment this out if you want this to be non-fatal
    if (result != WAIT_OBJECT_0)
        FatalError("MyWaitForSingleObject - Wait failed, you probably forgot to call release!");
    return (result == WAIT_OBJECT_0);
}

BOOL InitRWLock(RWLock *pLock)
{
    pLock->nReaderCount = 0;
    pLock->hDataLock = CreateSemaphore(NULL, 1, 1, NULL);
    if (pLock->hDataLock == NULL)
        return FALSE;
    pLock->hMutex = CreateMutex(NULL, FALSE, NULL);
    if (pLock->hMutex == NULL)
    {
        CloseHandle(pLock->hDataLock);
        return FALSE;
    }
    return TRUE;
}

BOOL DestroyRWLock(RWLock *pLock)
{
    DWORD result = WaitForSingleObject(pLock->hDataLock, 0);
    if (result == WAIT_TIMEOUT)
        return FatalError("DestroyRWLock - Can't destroy object, it's locked!");

    CloseHandle(pLock->hMutex);
    CloseHandle(pLock->hDataLock);
    return TRUE;
}

BOOL AcquireReadLock(RWLock *pLock)
{
    BOOL result = TRUE;

    if (!MyWaitForSingleObject(pLock->hMutex))
        return FALSE;
 
    if(++pLock->nReaderCount == 1)
        result = MyWaitForSingleObject(pLock->hDataLock);

    ReleaseMutex(pLock->hMutex);
    return result;
}

BOOL ReleaseReadLock(RWLock *pLock)
{
    int result;
    LONG lPrevCount;

    if (!MyWaitForSingleObject(pLock->hMutex))
        return FALSE;

    if (--pLock->nReaderCount == 0)
        result = ReleaseSemaphore(pLock->hDataLock, 1, &lPrevCount);

    ReleaseMutex(pLock->hMutex);
    return result;
}

BOOL AcquireWriteLock(RWLock *pLock)
{
    return MyWaitForSingleObject(pLock->hDataLock);
}

BOOL ReleaseWriteLock(RWLock *pLock)
{
    int result;
    LONG lPrevCount;

    result = ReleaseSemaphore(pLock->hDataLock, 1, &lPrevCount);
    if (lPrevCount != 0)
        FatalError("ReleaseWriteLock - Semaphore was not locked!");
    return result;
}

BOOL ReadOK(RWLock *pLock)
{
    // This check is not perfect, because we
    // do not know for sure if we are one of
    // the readers.
    return (pLock->nReaderCount > 0);
}

BOOL WriteOK(RWLock *pLock)
{
    DWORD result;

    // The first reader may be waiting in the mutex,
    // but any more than that is an error.
    if (pLock->nReaderCount > 1)
        return FALSE;

    // This check is not perfect, because we
    // do not know for sure if this thread was
    // the one that had the semaphore locked.
    result = WaitForSingleObject(pLock->hDataLock, 0);
    if (result == WAIT_TIMEOUT)
        return TRUE;

    // a count is kept, which was incremented in Wait.
    result = ReleaseSemaphore(pLock->hDataLock, 1, NULL);
    if (result == FALSE)
        FatalError("WriteOK - ReleaseSemaphore failed");
    return FALSE;
}

///////////////////////////////////////////////////////

/*
 * Error handler
 */
BOOL FatalError(char *s)
{
    fprintf(stdout, "%s\n", s);
    // Comment out exit() to prevent termination
    exit(EXIT_FAILURE);
    return FALSE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -