代码之家  ›  专栏  ›  技术社区  ›  cong

如何使用pthread\u mutex\u destroy在Linux中安全正确地销毁互斥体?

  •  6
  • cong  · 技术社区  · 7 年前

    APUE 3rd ,11.6.1互斥体,本章中有一个关于锁定和解锁互斥体的示例:

    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_unlock pthread_mutex_destroy : B螺纹 pthread_mutex_lock 之间 pthread\u mutex\u解锁 在里面 这将导致未定义的行为(“试图破坏锁定的互斥锁会导致未定义的行为”)。

    我说得对吗?如果我是对的,那么,如何使其正常工作,或者如何使用 pthread\u mutex\u destroy

    1 回复  |  直到 6 年前
        1
  •  3
  •   Michael Burr    7 年前

    pthread_mutex_destroy() 说:

    销毁已解锁的初始化互斥体应是安全的。

    pthread_mutex_unlock() else 合同条款 if 中的声明 foo_rele() 那么线程A调用是安全的 pthread\u mutex\u destroy() pthread\u mutex\u unlock() 呼叫已解锁互斥锁。

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

    在本例中,我们忽略了线程在调用之前如何绑定对象 foo_hold . 即使引用计数为零,对于 foo_rele 如果在调用时在互斥体上阻塞了另一个线程,则释放对象内存 foo_hold公司