数据结构与算法4 — 高并发栈

尊重作者劳动成果,转载请注明出处,谢谢!

1. concurrentStack.h

#ifndef concurrentStack_H
#define concurrentStack_H

#include "types.h"
#include <pthread.h>

//栈节点
typedef struct stackNode
{
    void *data;             //数据
    struct stackNode *next; //下一节点
} StackNode;

//高并发栈,采用链表的实现方式,提供后进先出的数据访问方式,支持多线程的安全访问,支持多种数据类型,包括:int、struct等
typedef struct
{
    StackNode *top;       //头节点(栈顶,NULL表示栈为空)
    size_t dataSize;      //数据大小(字节)
    size_t size;          //栈大小
    pthread_mutex_t lock; //栈锁
} ConcurrentStack;

//定义该宏可以直观的看出栈元素的数据类型,比如:ConcurrentStack(int)
#define ConcurrentStack(type) ConcurrentStack

#ifdef __cplusplus
extern "C"
{
#endif
    boolean concurrentStack_init(ConcurrentStack *stack, size_t dataSize);
    void concurrentStack_free(ConcurrentStack *stack);
    void concurrentStack_clear(ConcurrentStack *stack);
    size_t concurrentStack_length(ConcurrentStack *stack);
    boolean concurrentStack_empty(ConcurrentStack *stack);
    boolean concurrentStack_push(ConcurrentStack *stack, const void *data);
    boolean concurrentStack_pop(ConcurrentStack *stack, void *data);
    void *concurrentStack_top(ConcurrentStack *stack, void *data);
#ifdef __cplusplus
}
#endif

#endif

2. concurrentStack.c

#include "concurrentStack.h"
#include <string.h>
#include <stdlib.h>

//创建栈节点
static StackNode *stackNode_create(const void *data, size_t dataSize)
{
    StackNode *node = (StackNode *)malloc(sizeof(StackNode));
    if (node == NULL)
        return NULL;

    memset(node, 0, sizeof(StackNode));
    node->data = malloc(dataSize);
    if (node->data == NULL)
    {
        free(node);
        return NULL;
    }

    memcpy(node->data, data, dataSize);
    node->next = NULL;
    return node;
}

//释放栈节点
static void stackNode_free(StackNode *node)
{
    if (node == NULL)
        return;

    node->next = NULL;
    if (node->data != NULL)
    {
        free(node->data);
        node->data = NULL;
    }

    free(node);
}

//初始化
boolean concurrentStack_init(ConcurrentStack *stack, size_t dataSize)
{
    if (stack == NULL || dataSize <= 0)
        return False;

    pthread_mutex_init(&stack->lock, NULL);
    stack->top = NULL;
    stack->size = 0;
    stack->dataSize = dataSize;
    return True;
}

//释放内存
void concurrentStack_free(ConcurrentStack *stack)
{
    if (stack == NULL)
        return;

    concurrentStack_clear(stack);
    stack->dataSize = 0;
    pthread_mutex_destroy(&stack->lock);
}

//清空栈
void concurrentStack_clear(ConcurrentStack *stack)
{
    if (stack == NULL)
        return;

    pthread_mutex_lock(&stack->lock);
    StackNode *top;
    while (stack->top != NULL)
    {
        top = stack->top;
        stack->top = top->next;
        stackNode_free(top);
    }

    stack->top = NULL;
    stack->size = 0;
    pthread_mutex_unlock(&stack->lock);
}

//获取栈长度
size_t concurrentStack_length(ConcurrentStack *stack)
{
    if (stack == NULL || stack->top == NULL)
        return 0;

    return stack->size;
}

//判断栈是否为空
boolean concurrentStack_empty(ConcurrentStack *stack)
{
    if (stack == NULL)
        return True;

    return stack->top == NULL ? True : False;
}

//入栈
boolean concurrentStack_push(ConcurrentStack *stack, const void *data)
{
    if (stack == NULL)
        return False;

    StackNode *node = stackNode_create(data, stack->dataSize);
    if (node == NULL)
        return False;

    pthread_mutex_lock(&stack->lock);

    node->next = stack->top;
    stack->top = node;
    stack->size++;

    pthread_mutex_unlock(&stack->lock);
    return True;
}

//出栈
boolean concurrentStack_pop(ConcurrentStack *stack, void *data)
{
    if (stack == NULL)
        return False;

    pthread_mutex_lock(&stack->lock);

    if (concurrentStack_empty(stack)) //栈空
    {
        pthread_mutex_unlock(&stack->lock);
        return False;
    }

    if (data != NULL)
        memcpy(data, stack->top->data, stack->dataSize);

    StackNode *top = stack->top;
    stack->top = top->next;
    stack->size--;
    stackNode_free(top);

    pthread_mutex_unlock(&stack->lock);
    return True;
}

//获取栈顶元素指针
void *concurrentStack_top(ConcurrentStack *stack, void *data)
{
    if (stack == NULL)
        return NULL;

    pthread_mutex_lock(&stack->lock);

    if (concurrentStack_empty(stack)) //栈空
    {
        pthread_mutex_unlock(&stack->lock);
        return NULL;
    }

    void *top = stack->top->data;
    if (data != NULL)
        memcpy(data, top, stack->dataSize);

    pthread_mutex_unlock(&stack->lock);
    return top;
}
原文地址:https://www.cnblogs.com/chenyuxin/p/15215093.html