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

#define NHASH 29
#define HASH(fp) (((unsigned long)fp)%NHASH)

struct foo *fh[NHASH];
pthread_mutex_t hashlock = PTHREAD_MUTEX_INITIALIZER;

struct foo{
    int f_count;
    pthread_mutex_t f_lock;
    struct foo *f_next;
    int f_id;
};

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

if((fp = malloc(sizeof(struct foo))) != NULL){
        fp->f_count = 1;
        if (pthread_mutex_init(&fp->f_lock, NULL) != 0) {
            free(fp);
            return (NULL);
        }
        idx = HASH(fp);
        pthread_mutex_lock(&hashlock);
        fp->f_next = fh[idx];
        fh[idx] = fp->f_next;
        pthread_mutex_lock(&fp->f_lock);
        pthread_mutex_unlock(&hashlock);
        // continue initialization
    }
    return (fp);
}

void foo_hold(struct foo *fp){
    pthread_mutex_lock(&hashlock);
    fp->f_count++;
    pthread_mutex_unlock(&hashlock);
}

struct foo *foo_find(int id){
    struct foo *fp;
    int idx;

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

void foo_release(struct foo *fp){
    struct foo *tfp;
    int idx;

pthread_mutex_lock(&hashlock);
    if(--fp->f_count == 0){
        idx = HASH(fp);
        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(&hashlock);
        }
}

int main(void)
{
    printf("Hello World!\n");
    return 0;
}

Unix系统编程_cha11.6_线程同步的更多相关文章

  1. 《Linux/Unix系统编程手册》读书笔记8 (文件I/O缓冲)

    <Linux/Unix系统编程手册>读书笔记 目录 第13章 这章主要将了关于文件I/O的缓冲. 系统I/O调用(即内核)和C语言标准库I/O函数(即stdio函数)在对磁盘进行操作的时候 ...

  2. 《Linux/Unix系统编程手册》读书笔记7 (/proc文件的简介和运用)

    <Linux/Unix系统编程手册>读书笔记 目录 第11章 这章主要讲了关于Linux和UNIX的系统资源的限制. 关于限制都存在一个最小值,这些最小值为<limits.h> ...

  3. 《Linux/Unix系统编程手册》读书笔记2

    <Linux/Unix系统编程手册>读书笔记 目录 第5章: 主要介绍了文件I/O更深入的一些内容. 原子操作,将一个系统调用所要完成的所有动作作为一个不可中断的操作,一次性执行:这样可以 ...

  4. 《Linux/Unix系统编程手册》 时间子系统

    Linux下操作系统编程有两本经典APUE即<Advanced Programming in the UNIX Environment>和TLPI<The Linux Program ...

  5. 《Linux/UNIX系统编程手册》第63章 IO多路复用、信号驱动IO以及epoll

    关键词:fasync_helper.kill_async.sigsuspend.sigaction.fcntl.F_SETOWN_EX.F_SETSIG.select().poll().poll_wa ...

  6. 《Linux/Unix系统编程手册》读书笔记 目录

    <Linux/Unix系统编程手册>读书笔记1  (创建于4月3日,最后更新4月7日) <Linux/Unix系统编程手册>读书笔记2  (创建于4月9日,最后更新4月10日) ...

  7. 《Linux/Unix系统编程手册》读书笔记9(文件属性)

    <Linux/Unix系统编程手册>读书笔记 目录 在Linux里,万物皆文件.所以文件系统在Linux系统占有重要的地位.本文主要介绍的是文件的属性,只是稍微提及一下文件系统,日后如果有 ...

  8. 《Linux/Unix系统编程手册》读书笔记6

    <Linux/Unix系统编程手册>读书笔记 目录 第9章 这章主要讲了一堆关于进程的ID.实际用户(组)ID.有效用户(组)ID.保存设置用户(组)ID.文件系统用户(组)ID.和辅助组 ...

  9. 《Linux/Unix系统编程手册》读书笔记5

    <Linux/Unix系统编程手册>读书笔记 目录 第8章 本章讲了用户和组,还有记录用户的密码文件/etc/passwd,shadow密码文件/etc/shadow还有组文件/etc/g ...

随机推荐

  1. 如何在 Arch Linux 的终端里设定 WiFi 网络

    如果你使用的是其他 Linux 发行版 而不是 Arch CLI,那么可能会不习惯在终端里设置 WiFi.尽管整个过程有点简单,不过我还是要讲一下.在这篇文章里,我将带领新手们通过一步步的设置向导,把 ...

  2. MySQL逻辑备份与恢复

    备份:mysqldump -uroot -p yyzc department > /home/admin/yyzc_backup.sql 恢复:mysql -uroot -p yyzc < ...

  3. python urllib2使用心得

    python urllib2使用心得 1.http GET请求 过程:获取返回结果,关闭连接,打印结果 f = urllib2.urlopen(req, timeout=10) the_page = ...

  4. 多线程下载的原理&断点下载的原理

    1)多线程下载说明:

  5. (转)CSS3 @font-face

    @font-face是CSS3中的一个模块,他主要是把自己定义的Web字体嵌入到你的网页中,随着@font-face模块的出现,我们在Web的开发中使用字体不怕只能使用Web安全字体,你们当中或许有许 ...

  6. Cannot attach the file as database 'membership'.

    Cannot attach the file 'D:\GitHome\cae\CAE\App_Data\membership.mdf' as database 'membership'. 说明: 执行 ...

  7. linux用命令行来执行php程序

    <?php $start = microtime(true); for($i=0 ; $i <10000 ; $i ++){ // echo '正在执行第'.$i.'个操作! '.PHP_ ...

  8. IIS计数器

    Bytes Total/sec 是 Bytes Sent/sec 与 Bytes Received/sec 的总和.这是 Web 服务每秒传输的总字节数. Cache Total Turnover R ...

  9. 安装ruby

    (这些文章都是从我的个人主页上粘贴过来的,大家也可以访问我的主页 www.iwangzheng.com) 过程中有点小曲折,我们leader是技术大牛,现在我生命中多了个超高智商处女座man了,还有一 ...

  10. C#装箱和拆箱(值类型和引用类型之间的转换)

    面向对象编程中,封箱指把非对象类型的数值或数据,包装成对象类型反之,拆箱指把对象类型拆成非对象的数值或数据. 例子:定义一个Circle 类 class Circle { double radius; ...