c - 如何使用 pthread_mutex_destroy 在 Linux 中安全正确地销毁互斥量?

标签 c linux pthreads mutex race-condition

我读到了 APUE 3rd , 11.6.1 Mutexes, 本章有一个关于锁定和解锁互斥锁的例子:

struct foo {
    int             f_count;
    pthread_mutex_t f_lock;
    int             f_id;
    /* ... more stuff here ... */
};

struct foo *
foo_alloc(int id) /* allocate the object */
{
    struct foo *fp;

    if ((fp = malloc(sizeof(struct foo))) != NULL) {
        fp->f_count = 1;
        fp->f_id = id;
        if (pthread_mutex_init(&fp->f_lock, NULL) != 0) {
            free(fp);
            return(NULL);
        }
        /* ... continue initialization ... */
    }
    return(fp);
}

void
foo_hold(struct foo *fp) /* add a reference to the object */
{
    pthread_mutex_lock(&fp->f_lock);
    fp->f_count++;
    pthread_mutex_unlock(&fp->f_lock);
}

void
foo_rele(struct foo *fp) /* release a reference to the object */
{
    pthread_mutex_lock(&fp->f_lock);
    if (--fp->f_count == 0) { /* last reference */
        pthread_mutex_unlock(&fp->f_lock);
        pthread_mutex_destroy(&fp->f_lock);
        free(fp);
    } else {
        pthread_mutex_unlock(&fp->f_lock);
    }
}

foo_rele中,pthread_mutex_unlockpthread_mutex_destroy之间存在竞争条件:B线程可以调用pthread_mutex_lockpthread_mutex_unlockpthread_mutex_destroy 之间 A thread 这将导致未定义的行为(“试图销毁锁定的互斥量导致未定义行为”)。

我说的对吗?如果我是对的,那么,如何让它正常工作或如何在 Linux 中使用 pthread_mutex_destroy 安全正确地销毁互斥体?

最佳答案

pthread_mutex_destroy() 的 POSIX 规范说:

It shall be safe to destroy an initialized mutex that is unlocked.

这意味着如果线程 B 调用 pthread_mutex_unlock()else if 的条款foo_rele() 中的声明那么线程 A 调用 pthread_mutex_destroy() 是安全的因为它只能在线程 B 的 pthread_mutex_unlock() 之后到达那里调用已解锁互斥量。

所有这些都假设引用计数是正确的,这样在线程 A 解锁互斥量后,其他线程无法从 0 -> 1 递增计数。换句话说,在引用计数下降到 0 时,不可能有另一个线程可能调用 foo_hold()。 .

APUE 在示例代码之后的解释中提到了这一点:

In this example, we have ignored how threads find an object before calling foo_hold. Even though the reference count is zero, it would be a mistake for foo_rele to free the object’s memory if another thread is blocked on the mutex in a call to foo_hold. We can avoid this problem by ensuring that the object can’t be found before freeing its memory. We’ll see how to do this in the examples that follow.

关于c - 如何使用 pthread_mutex_destroy 在 Linux 中安全正确地销毁互斥量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46345261/

相关文章:

c++ - 为什么我的指针不是结构或 union ?

c++ - 关于 ZeroMQ 和使用替代存储来存储消息

c++ - 如何唤醒休眠的 pthread?

c - "kill"如何成为Pthread?

c - linux mkdir函数无法授权完全权限

c - 在 c 中使用 p 线程编写并行快速排序

c - 有符号距离场计算错误

c - 我在 "return"中看到一些我不明白的代码。有人可以帮助我吗?

c - 为函数内部结构体的字符数组指针分配内存

linux - 电子邮件中的 df nice 输出格式