当前位置: 首页 > news >正文

墙外必去的网站网站数据比较

墙外必去的网站,网站数据比较,技术好的手机网站建设,网站商城支付接口基础知识 rcu-read copy update的缩写。和读写锁起到相同的效果。据说牛逼一点。对于我们普通程序员#xff0c;要先学会使用#xff0c;再探究其内部原理。 链表的数据结构#xff1a; struct list_head {struct list_head *next, *prev; };还有一种#xff1a;struct h…基础知识  rcu-read copy update的缩写。和读写锁起到相同的效果。据说牛逼一点。对于我们普通程序员要先学会使用再探究其内部原理。 链表的数据结构 struct list_head {struct list_head *next, *prev; };还有一种struct hlist_head本文不做该链表的测试。 struct hlist_head {struct hlist_node *first; };struct hlist_node {struct hlist_node *next, **pprev; }; 涉及的文件include\linux\rculist.h 初始化链表INIT_LIST_HEAD_RCU /** INIT_LIST_HEAD_RCU - Initialize a list_head visible to RCU readers* list: list to be initialized** You should instead use INIT_LIST_HEAD() for normal initialization and* cleanup tasks, when readers have no access to the list being initialized.* However, if the list being initialized is visible to readers, you* need to keep the compiler from being too mischievous.*/ static inline void INIT_LIST_HEAD_RCU(struct list_head *list) {WRITE_ONCE(list-next, list);WRITE_ONCE(list-prev, list); } 添加节点list_add_rcu(插入到头节点后面) /*** list_add_rcu - add a new entry to rcu-protected list* new: new entry to be added* head: list head to add it after** Insert a new entry after the specified head.* This is good for implementing stacks.** The caller must take whatever precautions are necessary* (such as holding appropriate locks) to avoid racing* with another list-mutation primitive, such as list_add_rcu()* or list_del_rcu(), running on this same list.* However, it is perfectly legal to run concurrently with* the _rcu list-traversal primitives, such as* list_for_each_entry_rcu().*/ static inline void list_add_rcu(struct list_head *new, struct list_head *head) {__list_add_rcu(new, head, head-next); } 添加节点list_add_tail_rcu(插入到头节点前面就是链尾)  /*** list_add_tail_rcu - add a new entry to rcu-protected list* new: new entry to be added* head: list head to add it before** Insert a new entry before the specified head.* This is useful for implementing queues.** The caller must take whatever precautions are necessary* (such as holding appropriate locks) to avoid racing* with another list-mutation primitive, such as list_add_tail_rcu()* or list_del_rcu(), running on this same list.* However, it is perfectly legal to run concurrently with* the _rcu list-traversal primitives, such as* list_for_each_entry_rcu().*/ static inline void list_add_tail_rcu(struct list_head *new,struct list_head *head) {__list_add_rcu(new, head-prev, head); } 删除节点list_del_rcu /*** list_del_rcu - deletes entry from list without re-initialization* entry: the element to delete from the list.** Note: list_empty() on entry does not return true after this,* the entry is in an undefined state. It is useful for RCU based* lockfree traversal.** In particular, it means that we can not poison the forward* pointers that may still be used for walking the list.** The caller must take whatever precautions are necessary* (such as holding appropriate locks) to avoid racing* with another list-mutation primitive, such as list_del_rcu()* or list_add_rcu(), running on this same list.* However, it is perfectly legal to run concurrently with* the _rcu list-traversal primitives, such as* list_for_each_entry_rcu().** Note that the caller is not permitted to immediately free* the newly deleted entry. Instead, either synchronize_rcu()* or call_rcu() must be used to defer freeing until an RCU* grace period has elapsed.*/ static inline void list_del_rcu(struct list_head *entry) {__list_del_entry(entry);entry-prev LIST_POISON2; } 删除尾节点hlist_del_init_rcu  /*** hlist_del_init_rcu - deletes entry from hash list with re-initialization* n: the element to delete from the hash list.** Note: list_unhashed() on the node return true after this. It is* useful for RCU based read lockfree traversal if the writer side* must know if the list entry is still hashed or already unhashed.** In particular, it means that we can not poison the forward pointers* that may still be used for walking the hash list and we can only* zero the pprev pointer so list_unhashed() will return true after* this.** The caller must take whatever precautions are necessary (such as* holding appropriate locks) to avoid racing with another* list-mutation primitive, such as hlist_add_head_rcu() or* hlist_del_rcu(), running on this same list. However, it is* perfectly legal to run concurrently with the _rcu list-traversal* primitives, such as hlist_for_each_entry_rcu().*/ static inline void hlist_del_init_rcu(struct hlist_node *n) {if (!hlist_unhashed(n)) {__hlist_del(n);n-pprev NULL;} } 替换list_replace_rcu /*** list_replace_rcu - replace old entry by new one* old : the element to be replaced* new : the new element to insert** The old entry will be replaced with the new entry atomically.* Note: old should not be empty.*/ static inline void list_replace_rcu(struct list_head *old,struct list_head *new) {new-next old-next;new-prev old-prev;rcu_assign_pointer(list_next_rcu(new-prev), new);new-next-prev new;old-prev LIST_POISON2; } 计算长度 判空list_empty 链表尾空时返回值为1链表不空时返回0。 下面这段注释的大体含义就是当你想用list_empty_rcu的时候list_empty就足够满足需要了。 /** Why is there no list_empty_rcu()? Because list_empty() serves this* purpose. The list_empty() function fetches the RCU-protected pointer* and compares it to the address of the list head, but neither dereferences* this pointer itself nor provides this pointer to the caller. Therefore,* it is not necessary to use rcu_dereference(), so that list_empty() can* be used anywhere you would want to use a list_empty_rcu().*/ 获取节点对应的数据list_entry_rcu /*** list_entry_rcu - get the struct for this entry* ptr: the struct list_head pointer.* type: the type of the struct this is embedded in.* member: the name of the list_head within the struct.** This primitive may safely run concurrently with the _rcu list-mutation* primitives such as list_add_rcu() as long as its guarded by rcu_read_lock().*/ #define list_entry_rcu(ptr, type, member) \container_of(READ_ONCE(ptr), type, member) 遍历 list_for_each_entry_rcu /*** list_for_each_entry_rcu - iterate over rcu list of given type* pos: the type * to use as a loop cursor.* head: the head for your list.* member: the name of the list_head within the struct.* cond: optional lockdep expression if called from non-RCU protection.** This list-traversal primitive may safely run concurrently with* the _rcu list-mutation primitives such as list_add_rcu()* as long as the traversal is guarded by rcu_read_lock().*/ #define list_for_each_entry_rcu(pos, head, member, cond...) \for (__list_check_rcu(dummy, ## cond, 0), \pos list_entry_rcu((head)-next, typeof(*pos), member); \pos-member ! (head); \pos list_entry_rcu(pos-member.next, typeof(*pos), member)) 链表综合实验代码 测试内容包括添加、计算长度、遍历数据、删除节点、替换节点。最后在卸载函数中释放链表资源。 #include linux/module.h #include linux/init.h #include linux/rculist.h #include linux/slab.h #include linux/vmalloc.h#define _DEBUG_INFO #ifdef _DEBUG_INFO#define DEBUG_INFO(format,...) \printk(KERN_ERR%s:%d -- format\n,\__func__,__LINE__,##__VA_ARGS__) #else#define DEBUG_INFO(format,...) #endifstruct rcu_private_data{struct list_head list; };struct my_list_node{struct list_head node;int number; };static int list_size(struct rcu_private_data *p){struct my_list_node *pos;struct list_head *head p-list;int count 0;if(list_empty(p-list)){DEBUG_INFO(list is empty);return 0;}else{DEBUG_INFO(list is not empty);}list_for_each_entry_rcu(pos,head,node){count;}return count; }//遍历链表 void show_list_nodes(struct rcu_private_data *p){struct my_list_node *pos;struct list_head *head p-list;if(list_empty(p-list)){DEBUG_INFO(list is empty);return;}else{DEBUG_INFO(list is not empty);}list_for_each_entry_rcu(pos,head,node){DEBUG_INFO(pos-number %d,pos-number);} }//清空链表 void del_list_nodes(struct rcu_private_data *p){struct my_list_node *pos;struct list_head *head p-list;if(list_empty(p-list)){DEBUG_INFO(list is empty);return;}else{DEBUG_INFO(list is not empty);}list_for_each_entry_rcu(pos,head,node){DEBUG_INFO(pos-number %d\n,pos-number);vfree(pos);} }struct rcu_private_data *prpd;static int __init ch02_init(void){int i 0;static struct my_list_node * new[6];struct rcu_private_data *p (struct rcu_private_data*)vmalloc(sizeof(struct rcu_private_data));prpd p;INIT_LIST_HEAD_RCU(p-list);DEBUG_INFO(list_empty(p-list) %d,list_empty(p-list));for(i 0;i 5;i){new[i] (struct my_list_node*)vmalloc(sizeof(struct my_list_node));INIT_LIST_HEAD_RCU(new[i]-node);new[i]-number i;list_add_rcu(new[i]-node,p-list);}DEBUG_INFO(list_size %d,list_size(p));//添加后的结果应该是5 4 3 2 1//遍历链表show_list_nodes(p);//删除链表节点 new[3];list_del_rcu(new[3]-node);vfree(new[3]);DEBUG_INFO(list_size %d,list_size(p));//遍历链表show_list_nodes(p);//替换一个链表节点new[5] (struct my_list_node*)vmalloc(sizeof(struct my_list_node));INIT_LIST_HEAD_RCU(new[5]-node);new[5]-number i;list_replace_rcu(new[1]-node,new[5]-node);vfree(new[1]);//遍历链表show_list_nodes(p);DEBUG_INFO(init);return 0; }static void __exit ch02_exit(void){del_list_nodes(prpd);vfree(prpd);DEBUG_INFO(exit); }module_init(ch02_init); module_exit(ch02_exit); MODULE_LICENSE(GPL); 测试 加载模块 卸载模块  小结
http://www.huolong8.cn/news/307364/

相关文章:

  • 常德地区网站建设百度提交入口怎么用
  • 一个网站同时做百度和360 百度商桥都可以接收客户信息吗个人网站设计实验原理
  • 网站文件命名规则荥阳市建设局网站
  • 笔记本做网站服务器无忧网站优化
  • 网站必须做百度推广才能被别人搜到吗顺义企业建站费用
  • 做影视网站的软件网站设计师待遇
  • 高端网站设计 新鸿儒自己做的网站怎么上传到网络
  • 个人网站主题深圳市做网站
  • c asp.net网站开发书企业管理软件下载
  • 网站建设需要注意什么 知乎滑县网站建设服务
  • 移动版wordpress优化方案英语答案
  • 网站开发为什么需要团队完成增加网站关键词库
  • 源码 网站建设教程湖北十堰了不得科技网络公司
  • 酒店网站开发使用h5做的学习网站源码
  • 呼和浩特整站优化网站关键词优化系统
  • 阳谷建网站网站开发不懂英语
  • 国税网站模板重庆建设工程信息网最新网站
  • 扬州市市政建设处网站软考中级科目难度排行
  • 网站主页调用做网站1500全包
  • 爬虫做视频网站重庆市建设信息网站
  • 世界上做的最好的前端网站电脑怎么建网站详细步骤
  • seo网站排名软件c 网站开发网易云课堂百度云下载
  • 云存储能用来做网站吗长春市住房和城乡建设局网站
  • 广东网站建设方便如何看访问网站的dns
  • 网站seo分析报告案例建筑类电商网站
  • 必应网站管理员工具网站开发交流吧
  • 郑州餐饮 网站建设wordpress模板加密
  • 怎么做二级网站要查询一个网站在什么公司做的推广怎么查
  • 网站站长要会什么用杭州网站界面设计
  • 泰州专门做网站access 做网站 出现问题