首先感谢齐海谦的辛勤劳动,理论及例子都很清晰:)
ref : http://blog.csdn.net/rain0993/article/details/8463568
(基本的数据结构学习笔记:kref)PS:关于kref的用法,基本是翻译kref.txt的,有些东西还没完全理解,待续吧……
其实只要理解了那3个规则,就知道该如何使用kref了,可惜啊,没有完全理解透,提几个问题,待以后理解了再补上。
本人只是试着去解释,不正确的话,请多多指教
Q1:关于规则1,为何在将kref-ed结构体传递给另一个进程前,必须调用kref_get?不可以在另一个进程内部调用kref_get吗?
下面是因该是你说的情况:
void more_data_handling(void *cb_data)
{
struct my_data *data = cb_data;
kref_get(&data->refcount); //第一条
…
kref_put(&data->refcount, data_release);
}
int my_data_handler(void)
{
kref_init(&data->refcount);
task = kthread_run(more_data_handling, data, “more_data_handling”);
kref_put(&data->refcount, data_release); //第二条
…
}
A1: 加入执行顺序是: 第一条 —> 第二条 ,这种情况是正常的。
A2: 假如顺序是: 第二条 —> 第一条 ,这种情况 more_data_handling 会去操作已经内存释放的数据结构,后果可想而知
A3: 而且你永远不知道哪条语句先执行
Q2:为何不能将kfree传递给kref_put?为何要做这样的限制?
假如是 kref_put(&data->refcount, data_release);
kref_put(&data->refcount, kfree);
A1: 这种情况只能应付简单的数据结构或基本数据类型
A2: 很常见的情况:假如数据结构中有个链表指针,且需要循环释放,
就只能自定义释放函数了。
PS: 个人认为Kref很像C++里面的智能指针