Linux内核里的“智能指针” (续)

在上一篇文章《Linux内核里的智能指针》里介绍了Linux内核如何使用引用计数来更加安全的管理内存,本文承接前篇,主要介绍几点使用kref时的注意事项。

Linux内核文档kref.txt罗列了三条规则,我们在使用kref时必须遵守。

规则一:

If you make a non-temporary copy of a pointer, especially if  it can be passed to another thread of execution, you must  increment the refcount with kref_get() before passing it off;

规则二:

When you are done with a pointer, you must call kref_put();

规则三:

If the code attempts to gain a reference to a kref-ed structure without already holding a valid pointer, it must serialize access where a kref_put() cannot occur during the kref_get(), and the   structure must remain valid during the kref_get().

 

对于规则一,其实主要是针对多条执行路径(比如另起一个线程)的情况。如果是在单一的执行路径里,比如把指针传递给一个函数,是不需要使用kref_get的。看下面这个例子:

kref_init(&obj->ref);// do something here
// ...kref_get(&obj->ref);
call_something(obj);
kref_put(&obj->ref);// do something here
// ...kref_put(&obj->ref);

您是不是觉得call_something前后的一对kref_get和kref_put很多余呢?obj并没有逃出我们的掌控,所以它们确实是没有必要的。

但是当遇到多条执行路径的情况就完全不一样了,我们必须遵守规则一。下面是摘自内核文档里的一个例子:

struct my_data
{..struct kref refcount;..
};void data_release(struct kref *ref)
{struct my_data *data = container_of(ref, struct my_data, refcount);kfree(data);
}void more_data_handling(void *cb_data)
{struct my_data *data = cb_data;.. do stuff with data here.kref_put(&data->refcount, data_release);
}int my_data_handler(void)
{int rv = 0;struct my_data *data;struct task_struct *task;data = kmalloc(sizeof(*data), GFP_KERNEL);if (!data)return -ENOMEM;kref_init(&data->refcount);kref_get(&data->refcount);task = kthread_run(more_data_handling, data, "more_data_handling");if (task == ERR_PTR(-ENOMEM)) {rv = -ENOMEM;goto out;}.. do stuff with data here.out:kref_put(&data->refcount, data_release);return rv;
}

因为我们并不知道线程more_data_handling何时结束,所以要用kref_get来保护我们的数据。

注意规则一里的那个单词“before",kref_get必须是在传递指针之前进行,在本例里就是在调用kthread_run之前就要执行kref_get,否则,何谈保护呢?

 

对于规则二我们就不必多说了,前面调用了kref_get,自然要配对使用kref_put。

 

规则三主要是处理遇到链表的情况。我们假设一个情景,如果有一个链表摆在你的面前,链表里的节点是用引用计数保护的,那你如何操作呢?首先我们需要获得节点的指针,然后才可能调用kref_get来增加该节点的引用计数。根据规则三,这种情况下我们要对上述的两个动作串行化处理,一般我们可以用mutex来实现。请看下面这个例子:

static DEFINE_MUTEX(mutex);
static LIST_HEAD(q);
struct my_data
{struct kref  refcount;struct list_head link;
};static struct my_data *get_entry()
{struct my_data *entry = NULL;mutex_lock(&mutex);if (!list_empty(&q)) {entry = container_of(q.next, struct my_q_entry, link);kref_get(&entry->refcount);}mutex_unlock(&mutex);return entry;
}static void release_entry(struct kref *ref)
{struct my_data *entry = container_of(ref, struct my_data, refcount);list_del(&entry->link);kfree(entry);
}static void put_entry(struct my_data *entry)
{mutex_lock(&mutex);kref_put(&entry->refcount, release_entry);mutex_unlock(&mutex);
}

这个例子里已经用mutex来进行保护了,假如我们把mutex拿掉,会出现什么情况?记住,我们遇到的很可能是多线程操作。如果线程A在用container_of取得entry指针之后、调用kref_get之前,被线程B抢先执行,而线程B碰巧又做的是kref_put的操作,当线程A恢复执行时一定会出现内存访问的错误,所以,遇到这种情况一定要串行化处理。

 

我们在使用kref的时候要严格遵循这三条规则,才能安全有效的管理数据。

转载于:https://www.cnblogs.com/wwang/archive/2010/12/03/1895852.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/298828.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux主机名那点事儿

Linux主机名那点事儿和windows一样,liunx同样有自己的主机名,主要用于识别机器和远成访问。事儿一、/etc/hosts文件主机和IP配置文件该文件其实就是告诉本机哪些域名对应那些ip,那些主机名对应哪些ip,因为ip地址难以记忆&#xff…

数学老师出的谜语,语文老师已哭晕在厕所!

全世界只有3.14 % 的人关注了爆炸吧知识数学老师出的这几个谜语,谜面都是数字和运算符号,谜底可都是四个字的成语。语文老师已经哭晕了,快来试试看,你能猜出几个?谜面:0000点击下方空白区域查看答案▼谜底&…

swoole会合并到php吗,thinkphp整合swoole

cli模式下执行thinkphp1、cd 项目根目录2、php index.php admin/index/index --执行 模块/控制器/方法名异步消息队列1、服务器端核心代码/*** 脚本任务系统*/public function server(){$serv new \swoole_server("0.0.0.0", 8082);//日志会记录你错误的数据$serv-&…

自动Mock,让编写单元测试更简单

问题由于依赖注入,特别是构造函数注入的广泛使用,使得编写单元测试时,需要使用Mock框架(例如Moq)生成测试类的依赖接口的"模拟"实现,并验证接口是否按预期使用。例如eShopOnContainers中的测试代…

Linux下oracle11g 导入导出操作详细

//用dba匿名登录 [oracleenfo212 ~]$ sqlplus / as sysdba SQL*Plus: Release 11.2.0.1.0 Production on Wed May 8 16:39:53 2013 Copyright (c) 1982, 2009, Oracle. All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Prod…

苹果手机怎么拍星空_手机拍星空,看这篇教程就够了!

直到现在还有很多人觉得,只有单反才能拍出璀璨的星空。事实上,手机也能拍出非常好看的星空作品,只要掌握这些要点就足够了。点击下方视频,学习手机拍星空觉得视频太快的同学,可以接着往下看详细教程图文版下面我们来学…

如何用数学方法估算一个女生前男友的数量?

全世界只有3.14 % 的人关注了爆炸吧知识如果一个女生说,她集齐了十二个星座的前男友,我们应该如何估计她前男友的数量?小学生:这个问题相当简单公式:数据:{白羊座, 金牛座, 双子座, 巨蟹座, 狮子座, 处女座…

Discuz!NT博客非官方升级!!

接触Discuz!NT有很长的一段时间,从最初的神秘到现在的跃跃欲试,在这个九月最后一天,十一的前一天下午,终于完成了一次非官方升级!哈哈这次做的工作主要在博客方面进行了扩展,原则上是&#xff0…

弱事件 WeakEvent

虽然文章很少,但还是有的.引用一下 http://www.codeproject.com/KB/cs/WeakEvents.aspx http://www.cnblogs.com/rickiedu/archive/2007/03/15/676021.aspx http://www.cnblogs.com/Curry/archive/2008/10/30/1322647.html 事件一般都是内存泄露的源泉 建议参考此篇http://www.…

获取上传图片的大小 php,thinkphp5 获取上传图片的大小和信息

thinkphp5 获取上传图片的大小和信息先看一下打印出对象信息如下。object(think\File)#19 (13) {["error":"think\File":private] > string(0) ""["filename":protected] > string(77) "E:\WWW\im_liaosp\public\uploads\2…

我把负载均衡讲出了花,领导却不给我涨工资

“为什么负载均衡一般采用混合方式七层负载为什么比四层负载性能要低?四层负载概念真的对吗?文章较长,各位能不能持久到最后?image在正式开篇之前,先说几个瓜:硬件负载均衡的性能最高,其次是软件…

陪孩子看完这几部高分纪录片,胜过出国亲子游!

对孩子来说,好的纪录片就像是打开了一扇新世界的大门,让他们了解了更多大自然的奇妙之处。所以这次我们精心挑选了几部适合儿童观看的纪录片,其中绝大多数是导演专门为孩子拍摄的,大家可以在这期间和孩子一起观看哦。和普通的纪录…

Oracle行列转换的思考与总结

最近几天一直在弄Oracle-SQL的问题,涉及到了一些平时没有用到的东西,也因此而在这里郁闷了好久。现在问题得到了解决虽说不算完美。但是还是和大家一起分享一下。 行列转换之一:sum(case when.. then.. else.. end) as…

access对比数据_数据仓库系列之数据质量管理

数据质量一直是数据仓库领域一个比较令人头疼的问题,因为数据仓库上层对接很多业务系统,业务系统的脏数据,业务系统变更,都会直接影响数据仓库的数据质量。因此数据仓库的数据质量建设是一些公司的重点工作。一、数据质量数据质量…

深入浅出Google Android这本书怎么样

关于深入浅出Google Android 评论读后感:对入门的知识讲的很详细,近乎罗嗦,例子比较少而且不够吸引人。读后感:我还没收到货呢,昨天下午发的货,应该今天能到,因为是周末,我待会儿要回…

Php xml 目录,PHP-PHP+xml的无限分类树目录的方法?

无限分类树的代码有很多,下面是个示例:/**by lenush;*/class Tree{var $data array();var $child array(-1>array());var $layer array(-1>-1);var $parent array();function Tree ($value){$this->setNode(0, -1, $value);} // end funcfu…

Net 5.0 快速开发框架 YC.Boilerplate--框架介绍

YC.Boilerplate 框架介绍YC.Boilerplate 是一套快速开发框架,采用当下流行的前后端分离开发模式,前端 采用VUE、后端采用Net 5.0;框架实现了 多租户、动态webApi、多种ORM、IOC、数据库表和业务代码生成等等一系列模块,并开发了用…

老师:你根本不知道我有多想逃课

1 这个时候如果不小心吸了一口就是另一个故事了▼2 抓到一只正在吐泡泡的蓝胖子!▼3 腿短怎么了?我腿短我可爱!你学我是几个意思?▼4 我本以为这是一个温馨的故事▼5 老师:你根本想象不到我有多想逃课&#xff01…

允许服务与桌面交互_vivo 正式推出 Origin OS,融合自然设计与全新交互_搜狐汽车...

点击右上角关注我们,每天给您带来最新最潮的科技资讯,让您足不出户也知道科技圈大事!今天下午,vivo 推出了全新 Origin OS 手机系统。它采用了源于自然界的设计理念,同时加入了全新并且允许用户进行深度自定义的交互方…

有研究irrlicht引擎的吗,交流交流

我最近在研究这个开源引擎不知道irrlicht引擎和其他商业引擎比起来怎么样?这个引擎虽然没有IDE不过一直在更新,在进步。知道这个引擎的发表发表你的看法补充:最近找到了irrlicht中文官方论坛 有很多牛人是知名的网络游戏开发论坛和游戏玩家论坛忘了写网址…