无锁数组


2012-01-15

项目里有一个地方可能要去掉用于链表的锁,但是又得保证读写互斥。于是琢磨了一个土办法: (琢磨时的目标是用于异步发送日志,即多个日志存储者,一个发送者,接收者在另一个进程不用管它)

#define N 200
PVOID g_Buffer[N] = {0};
UINT  g_uSaveIndex = 0;

VOID 
    Save(
        PVOID pLog
    )
{
    UINT uMySaveIndex = 0;
    PVOID pOldLog = NULL;

    //
    // 获取目前可以操作的数组下标
    //
    uMySaveIndex = InterlockedIncrement(&g_uSaveIndex) % N;

    //
    // 存储日志
    //
    pOldLog = InterlockedExchangePointer(g_Buffer[uMySaveIndex], pLog);
    if (NULL != pOldLog)
    {
        //
        //     这个数组单元有老日志,释放这条老日志。
        //     (这条老日志距离本条日志中间已经有2000条日志了,
        // 这么久都没有发送出去,说明日志存储速度可能远大于发送速度,
        // 只能抛弃一部分日志了。
        //     如果不希望抛弃任何日志,那可以考虑使用链表,而不是用数组。
        //
    }

    return;
}

VOID 
    Send(
        VOID
    )
{
    static UINT uSendIndex = 0;
    PVOID pLogToSend = NULL;

    pLogToSend = InterlockedExchangePointer(g_Buffer[uSendIndex++ % N], NULL);

    //
    // 发送并清理日志
    // ...
    //

    return;
}