关于UNIX高级环境编程2 中第11章线程死锁的例程代码,看不懂 望高手指点

awangyong12345 2010-02-03 06:16:28
#include <stdlib.h>
#include <pthread.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; /* protected by hashlock */
int f_id;
/* ... more stuff here ... */
};

struct foo *
foo_alloc(void) /* allocate the object */
{
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 ... */
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;
int idx;

idx = HASH(fp);

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

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 */ // 矛盾1
pthread_mutex_unlock(&fp->f_lock);
pthread_mutex_lock(&hashlock);
pthread_mutex_lock(&fp->f_lock);
/* need to recheck the condition */
if (fp->f_count != 1) { //矛盾2
fp->f_count--;
pthread_mutex_unlock(&fp->f_lock);
pthread_mutex_unlock(&hashlock);
return;
}
/* remove from list */
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_unlock(&fp->f_lock);
pthread_mutex_destroy(&fp->f_lock);
free(fp);
} else {
fp->f_count--;
pthread_mutex_unlock(&fp->f_lock);
}
}

请教大家一个问题 这是UNXI高级环境编程第11章 讲线程死锁 的例程
有几个地方看不明白 想请问大家帮忙解释下 看不明白的地方已经注注释了 ,还有在foo_rele函数中 注释的矛盾1和矛盾2 两条语句 不是相互矛盾吗? 既然条件是 if(fp->f_count==1),那在它的嵌套里面为什么还有一个if(fp->f_count!=1),既然等于1才执行后面语句,那后面的!=1不是必然不成立的吗? 为什么还要写在这里? 请大家指教 谢谢大家
...全文
469 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
SnowerWkh 2011-12-16
  • 打赏
  • 举报
回复
第二个问题 是因为当pthread_mutex_unlock(&fp->f_lock),其他线程还可能对这个结构引用,可能使fp->f_count++,所以要再处理之前检查
晨星 2010-02-03
  • 打赏
  • 举报
回复
哦,对的,程序确实像是印错了。
对不起,我先入为主了。
应该是
fp->f_next = fh[idx];
fh[idx] = fp;
这样的。

不过刚才查了一下原书,发现也是那么印的。
olla168 2010-02-03
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 steedhorse 的回复:]
原来的头结点被fp的f_next指向,然后fp本身成了新的头,就是这么两步啊。
[/Quote]

感觉这里应该是这个意思,但是代码是不是应该这样?

        fp->f_next = fh[idx]; 
fh[idx] = fp;


awangyong12345 2010-02-03
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 steedhorse 的回复:]
原来的头结点被fp的f_next指向,然后fp本身成了新的头,就是这么两步啊。
[/Quote]

能将两句分开说吗? 第一执行后是什么情况,第二句执行后是什么情况,谢谢了
晨星 2010-02-03
  • 打赏
  • 举报
回复
从它的程序来看,fh是个哈希表,它有29个桶,每个桶用单向链表来组织,其中fh[i]就是各个单向链表的头指针。
感觉没法再详细了。:P
楼主可以复习一下《数据结构》课的相关内容呢。
awangyong12345 2010-02-03
  • 打赏
  • 举报
回复
谢谢 steedhorse 对这两句话的 解释,但是小弟非常愚笨,能否请大家说的清楚点,或则举个列子 谢谢了
晨星 2010-02-03
  • 打赏
  • 举报
回复
原来的头结点被fp的f_next指向,然后fp本身成了新的头,就是这么两步啊。
晨星 2010-02-03
  • 打赏
  • 举报
回复
这个两句执行下来,新的元素fp不就被插入到“fh[idx]”这个链表的头部了嘛。
awangyong12345 2010-02-03
  • 打赏
  • 举报
回复
fp->f_next = fh[idx]; // 请问这条语句的作用?
fh[idx] = fp->f_next; // 请问这条语句的作用?

请问这两句的作用是 请大家说清楚点 我的理解是 让fp->f_next指向fh[idx]指向的结构,但是一句 为什么又让fh[idx]指向的结构 指向fp->f_next 这有什么意义?
晨星 2010-02-03
  • 打赏
  • 举报
回复
楼主不了解哈希表么?
它这个哈希表的结构差不多也是世上最简单的:每个筒就是一个链表。
晨星 2010-02-03
  • 打赏
  • 举报
回复
#define HASH(fp) (((unsigned long)fp)%NHASH) // 请问这条语句的作用?
——就是定义一个宏,其功能是将一个给定的浮点数哈希到[0,29)之间,这差不多是世上最简单的Hash算法了。
晨星 2010-02-03
  • 打赏
  • 举报
回复
两个线程么,可能刚才还是1,一会再去测,已经不知啥时候被另一个线程给改成0了。

23,210

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧