首页 > 解决方案 > 使用 Semaphors 在 C 中创建线程安全堆栈?

问题描述

我正在尝试制作一个使用信号量实现线程安全的堆栈。当我将单个对象推入堆栈时它可以工作,但是一旦我尝试将第二个项目推入堆栈或从堆栈中弹出一个项目,终端就会冻结。这就是我到目前为止所拥有的,并且不确定我在哪里搞砸了。一切正常,但终端只是如前所述冻结

这是我创建堆栈的地方

sem_t selements, sspace;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;

BlockingStack *new_BlockingStack(int max_size)
{
    sem_init(&selements, 0, 0);
    sem_init(&sspace, 0, max_size);

    BlockingStack *newBlockingStack = malloc(sizeof(BlockingStack));
    newBlockingStack->maxSize = max_size;
    newBlockingStack->stackTop = -1;
    newBlockingStack->element = malloc(max_size * sizeof(void *));

    if (newBlockingStack == NULL)
    {
        return NULL;
    }

    if (newBlockingStack->element == NULL)
    {
        free(newBlockingStack);
        return NULL;
    }

    return newBlockingStack;
}

这里是 Push 和 Pop:

bool BlockingStack_push(BlockingStack *this, void *element)
{
    sem_wait(&sspace);
    pthread_mutex_lock(&m);


    if (this->stackTop == this->maxSize - 1)
    {
        return false;
    }
    if (element == NULL)
    {
        return false;
    }
    this->element[++this->stackTop] = element;
    return true;

    pthread_mutex_unlock(&m);
    sem_post(&selements);

}

void *BlockingStack_pop(BlockingStack *this)
{
    sem_wait(&selements);
    pthread_mutex_lock(&m);

    if (this->stackTop == -1)
    {
        return NULL;
    }
    else
    {
        return this->element[this->stackTop--];
    }

    pthread_mutex_unlock(&m);
    sem_post(&sspace);
}

标签: cmultithreadingstackmutexsemaphore

解决方案


为了线程安全,您已经使用了互斥锁 ( pthread_mutex_lock(&m) and pthread_mutex_unlock(&m))。为此目的,使用这种互斥就足够了。一旦一个线程获得互斥锁,其他线程就会阻塞pthread_mutex_lock(&m)调用。并且只有当前获取互斥锁的线程才能调用pthread_mutex_unlock(&m).


推荐阅读