[unix]两个互斥量保护共享变量自增,保证线程执行安全实例

#include "apue.h"
#include 

#define NHASH 29
#define HASH(id) (((unsigned long)id)%NHASH)
struct foo *fh[NHASH];
pthread_mutex_t hashlock = PTHREAD_MUTEX_INITIALIZER;

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

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

    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);
        }
        idx = HASH(id);
        pthread_mutex_lock(&hashlock);
        fp->f_next = fh[idx];
        fh[idx] = fp;
        pthread_mutex_lock(&fp->f_lock);
        pthread_mutex_unlock(&hashlock);
        /*continue initialization */
        pthread_mutex_unlock(&fp->f_lock);
    }
    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);
}

struct foo *
foo_find(int id)  /* find an existing object */
{
    struct foo *fp;

    pthread_mutex_lock(&hashlock);

    for(fp = fh[HASH(id)]; fp != NULL; fp = fp->f_next){
        if(fp->f_id == id){
            foo_hold(fp);
            break;
        }
    }
    pthread_mutex_unlock(&hashlock);
    return(fp);
}

#ifndef LOCK_MAX
void
foo_rele(struct foo *fp)  /* release a reference to the object */
{
    struct foo  *tfp;
    int             idx;

    pthread_mutex_lock(&fp->f_lock);
    if(fp->f_count == 1){  /*last reference*/
        pthread_mutex_unlock(&fp->f_lock);
        pthread_mutex_lock(&hashlock);
        pthread_mutex_lock(&fp->f_lock);
        /* need to recheck then condition*/
        if(fp->f_count != 1){
            fp->f_count--;
            pthread_mutex_unlock(&fp->f_lock);
            pthread_mutex_unlock(&hashlock);
            return;
        }
        /*remove from list*/
        idx = HASH(fp->f_id);
        tfp = fh[idx];
        if(tfp == fp){
            fh[idx] = fp->f_next;
        }else{
            while (tfp == fp)
                tfp = tfp->f_next;
            tfp->f_next = fp->f_next;
        }
        pthread_mutex_unlock(&hashlock);
        pthread_mutex_unlock(&fp->f_lock);
        pthread_mutex_destroy(&fp->f_lock);
        free(fp);
    }else{
        pthread_mutex_unlock(&fp->f_lock);
    }
}
#else
// 这里是粗粒度的锁
void
foo_rele(struct foo *fp)  /* release a reference to the object */
{
    struct foo  *tfp;
    int             idx;

    pthread_mutex_lock(&hashlock);
    if(--fp->f_count == 0){  /*last reference, remove from list*/
        idx = HASH(fp->f_id);
        tfp = fh[idx];
        if(tfp == fp){
            fh[idx] = fp->f_next;
        }else{
            while (tfp->f_next != fp)
                tfp = tfp->f_next;
            tfp->f_next = fp->f_next;
        }
        pthread_mutex_unlock(&hashlock);
        pthread_mutex_destroy(&fp->f_lock);
        free(fp);
    }else{
        pthread_mutex_unlock(&fp->f_lock);
    }
}

#endif  // LOCK_MAX

学无止境不耻下问:https://includestdio.com

你可能感兴趣的:(编程语言,系统)