日期:2014-05-16  浏览次数:20802 次

apue程序清单11-5的疑问
C/C++ code

#include <stdlib.h>
#include <pthread.h>

struct foo
{
    int f_count; //[color=#FF0000]引用计数[/color]
    pthread_mutex_t f_lock;
    /* ... more stuff here ... */
};

struct foo *foo_alloc(void)
{
    struct foo *fp;

    if ((fp = malloc(sizeof(struct foo))) != NULL)
    {
        fp->f_count = 1;

        if (pthread_mutex_init(&fp->f_lock, NULL) != 0)
        {
            free(fp);
            return NULL;
        }
        
        /* ... continue initialization ... */
    }
    return fp;
}

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

/* release a reference to the object */
void foo_rele(struct foo *fp)
{
    pthread_mutex_lock(&fp->f_lock);
    if (--fp->f_count == 0)
    {
        /* last reference */
        pthread_mutex_unlock(&fp->f_lock);
        //此处刚解锁别的线程恰好就调用了foo_hold会出现什么情况?
        pthread_mutex_destroy(&fp->f_lock);
        free(fp);
    }
    else
    {
        pthread_mutex_unlock(&fp->f_lock);
    }
}


还有,foo_hold函数在什么情况下使用呢,能否举个例子

------解决方案--------------------
基本原理看样你还是懂的,Mutex互斥访问,f_count是对象引用计数。

看不出这个例子有什么实际用途,因为根本一旦f_count减少为0然后foo被释放,其他持有该foo地址的用户完全是不知情的,会造成非法内存访问。

根据我个人开发经验,类似的应用场景是这样的:

foo作为一个句柄类,内部具有f_count引用计数,然后有一个引用对象是void *ref。引用计数是为ref服务的,不是为foo服务的,这个概念很重要。

构造一个foo要求传入一个对象,然后foo设置f_count=1,ref=obj; 这通常是由一个非并发环境引起的,之后该foo被传入到并发环境,大家就可以并发的操作了,希望持有对象就给它+1,释放持有就-1.

只有在f_count为0时,该foo句柄才可以free掉obj,而foo句柄自身则由非并发环境回收。