免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3817 | 回复: 8
打印 上一主题 下一主题

[C] 关于互斥量《APUE》 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-07-05 17:27 |只看该作者 |倒序浏览
本帖最后由 blackgenius 于 2010-07-05 18:08 编辑

CU的高手们,请指教一下APUE里面的一段关于互斥量的程序,本人菜鸟,无法理解,请求指点:
其中有两句,真不知道什么意思,
fp->f_next = fh[idx];
fh[idx] = fp->f_next;
请指点迷津
  1. #include <stdlib.h>
  2. #include <pthread.h>

  3. #define NHASH 29
  4. #define HASH(fp) (((unsigned long)fp)%NHASH)

  5. struct foo *fh[NHASH];

  6. pthread_mutex_t hashlock = PTHREAD_MUTEX_INITIALIZER;

  7. struct foo {
  8.         int             f_count;
  9.         pthread_mutex_t f_lock;
  10.         struct foo     *f_next; /* protected by hashlock */
  11.         int             f_id;
  12.         /* ... more stuff here ... */
  13. };

  14. struct foo *
  15. foo_alloc(void) /* allocate the object */
  16. {
  17.         struct foo      *fp;
  18.         int                     idx;

  19.         if ((fp = malloc(sizeof(struct foo))) != NULL) {
  20.                 fp->f_count = 1;
  21.                 if (pthread_mutex_init(&fp->f_lock, NULL) != 0) {
  22.                         free(fp);
  23.                         return(NULL);
  24.                 }
  25.                 idx = HASH(fp);
  26.                 pthread_mutex_lock(&hashlock);
  27.                 fp->f_next = fh[idx];
  28.                 fh[idx] = fp->f_next;
  29.                 pthread_mutex_lock(&fp->f_lock);
  30.                 pthread_mutex_unlock(&hashlock);
  31.                 /* ... continue initialization ... */
  32.                 pthread_mutex_unlock(&fp->f_lock);
  33.         }
  34. return(fp);
  35. }

  36. void
  37. foo_hold(struct foo *fp) /* add a reference to the object */
  38. {
  39.         pthread_mutex_lock(&fp->f_lock);
  40.         fp->f_count++;
  41.         pthread_mutex_unlock(&fp->f_lock);
  42. }

  43. struct foo *
  44. foo_find(int id) /* find an existing object */
  45. {
  46.         struct foo      *fp;
  47.         int                     idx;

  48.         idx = HASH(fp);
  49.         pthread_mutex_lock(&hashlock);
  50.         for (fp = fh[idx]; fp != NULL; fp = fp->f_next) {
  51.                 if (fp->f_id == id) {
  52.                         foo_hold(fp);
  53.                         break;
  54.                 }
  55.         }
  56.         pthread_mutex_unlock(&hashlock);
  57.         return(fp);
  58. }

  59. void
  60. foo_rele(struct foo *fp) /* release a reference to the object */
  61. {
  62.         struct foo      *tfp;
  63.         int                     idx;

  64.         pthread_mutex_lock(&fp->f_lock);
  65.         if (fp->f_count == 1) { /* last reference */
  66.                 pthread_mutex_unlock(&fp->f_lock);
  67.                 pthread_mutex_lock(&hashlock);
  68. pthread_mutex_lock(&fp->f_lock);
  69.                 /* need to recheck the condition */
  70.                 if (fp->f_count != 1) {
  71.                         fp->f_count--;
  72.                         pthread_mutex_unlock(&fp->f_lock);
  73.                         pthread_mutex_unlock(&hashlock);
  74.                         return;
  75.                 }
  76.                 /* remove from list */
  77.                 idx = HASH(fp);
  78.                 tfp = fh[idx];
  79.                 if (tfp == fp) {
  80.                         fh[idx] = fp->f_next;
  81.                 } else {
  82.                         while (tfp->f_next != fp)
  83.                                 tfp = tfp->f_next;
  84.                         tfp->f_next = fp->f_next;
  85.                 }
  86.                 pthread_mutex_unlock(&hashlock);
  87.                 pthread_mutex_unlock(&fp->f_lock);
  88.                 pthread_mutex_destroy(&fp->f_lock);
  89.                 free(fp);
  90.         } else {
  91.                 fp->f_count--;
  92.                 pthread_mutex_unlock(&fp->f_lock);
  93.         }
  94. }
  95.                                                                                                                                            105,1        底端
复制代码

论坛徽章:
0
2 [报告]
发表于 2010-07-05 20:44 |只看该作者
fp->f_next = fh[idx];
fh[idx] = fp->f_next;
这个写错了,应为:
fp->f_next = fh[idx];
fh[idx] = fp;

另外,find那个算法也错了

论坛徽章:
0
3 [报告]
发表于 2010-07-05 22:06 |只看该作者
回复 2# liwangli1983
谢谢指点啊~我菜鸟一个,自己是没法发现这些错误的~

论坛徽章:
0
4 [报告]
发表于 2010-07-05 23:23 |只看该作者
回复 2# liwangli1983


    能帮忙解释下
           idx = HASH(fp);

                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);
这段代码是什么意思?谢谢啦啊

论坛徽章:
0
5 [报告]
发表于 2010-07-06 08:46 |只看该作者
回复  liwangli1983
谢谢指点啊~我菜鸟一个,自己是没法发现这些错误的~
blackgenius 发表于 2010-07-05 22:06



我看到这块是也很疑惑,后来找到了英文版的勘误表,查到了这两处.

论坛徽章:
0
6 [报告]
发表于 2010-07-06 08:57 |只看该作者
回复  liwangli1983


    能帮忙解释下
           idx = HASH(fp);

                pthread_mut ...
单眼皮大姐 发表于 2010-07-05 23:23


fh是一个散列表,每一项都是struct foo型指针,面这个指针正好是一个struct foo型链表的头结点.
fp->f_next = fh[idx];
fh[idx] = fp;
就是把一个新的项插到链表的头结点.

论坛徽章:
0
7 [报告]
发表于 2010-07-06 09:56 |只看该作者
回复 6# liwangli1983


    就这句: idx = HASH(fp);干嘛用fp的地址%29之后当做fh的索引项,直接定义一个指针不也能帮助把一个新结点加入到链表中吗?我当时看这的时候就有些疑问,后来一知半解的就过去了,这次希望弄清楚,麻烦这位朋友帮忙讲讲,谢谢了

论坛徽章:
0
8 [报告]
发表于 2010-07-06 10:24 |只看该作者
回复  liwangli1983


    就这句: idx = HASH(fp);干嘛用fp的地址%29之后当做fh的索引项,直接定义一 ...
单眼皮大姐 发表于 2010-07-06 09:56



GOOGLE一下散列表吧
zv2051 该用户已被删除
9 [报告]
发表于 2013-03-20 22:24 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP