list_add_tail 双向链表实现分析

原文地址::https://blog.csdn.net/qingkongyeyue/article/details/76089257

相关文章

1、list_add_tail()----https://blog.csdn.net/kernel_details/article/details/1481390

转自http://www.xuebuyuan.com/1389026.html

在看内核v4l2示例代码driver/media/video/vivi.c时 ,看到list_add_tail()函数,现在对其进行分析:

 
  1. struct list_head {

  2. struct list_head *next, *prev;

  3. };

  4.  
  5. list_add_tail(&buf->vb.queue, &vid->active);

  6. /**

  7. * list_add_tail - add a new entry

  8. * @new: new entry to be added

  9. * @head: list head to add it before

  10. *

  11. * Insert a new entry before the specified head.

  12. * This is useful for implementing queues.

  13. */

  14. static __inline__ void list_add_tail(struct list_head *_new, struct list_head *head)

  15. {

  16. __list_add(_new, head->prev, head);

  17. }

  18.  
  19. /*

  20. * Insert a new entry between two known consecutive entries.

  21. *

  22. * This is only for internal list manipulation where we know

  23. * the prev/next entries already!

  24. */

  25. static __inline__ void __list_add(struct list_head * _new,

  26. struct list_head * prev,

  27. struct list_head * next)

  28. {

  29. next->prev = _new;

  30. _new->next = next;

  31. _new->prev = prev;

  32. prev->next = _new;

  33. }

  34.  

很多地方说:这个函数完成的功能就是添加一个新的结点在head的左边,其实不然,它是从右向左在head->priv和head两个节点之间插入_new。

假设刚开始建立链表,只有struct list_head *head,

那么前两句话有用:将next->prev = _new;
                            _new->next = next;

这就是将new节点添加到head 节点的左边,那么接 下来两句没用:   _new->prev = prev;  prev->next = _new;

如果head左边已近有了其他节点,那么调用list_add_tail()函数后,前边两句的功能一样,都是把新的节点添加在head左边,而后两句就是把新节点添加在原来head之前节点(head->priv)右边,这样就串起来了。

那list_add就反过来,把新的节点添加在head和head之后的节点(head->next)之间;

关于list_add和list_add_tail建立栈和FIFO:

list_add和list_add_tail都是在head两边插入新的节点,所以list_add先插入的节点向右移,head->next是最后插入的节点,list_add_tail先插入的节点向左移,head->next是最先插入的节点;

遍历链表都是从head开始向下,所以用list_add建立的链表先访问的是最后插入的节点,类似于栈;list_add_tail建立的链表先访问的是最先插入的节地点,类似于FIFO。

猜你喜欢

转载自blog.csdn.net/xqhrs232/article/details/81536312