Linux linked list Learning

Source: Internet
Author: User

I think every programmer knows the linked list very well. The structure is like a chain, one by one, and the access to it is a bit like a sugar gourd. If you want to eat the second one, you must first eat the first one. This is a one-way linked list. Of course, it also has more advanced features, such as cyclic linked list, bidirectional linked list, and bidirectional cyclic linked list. The standard linked list of the Linux kernel is a circular two-way circular linked list.
The linked list in Linux is a bit special. It does not have a header node, and its tail node directly points to the first node. Therefore, a large ring is formed, so each node is a header node. You can start from any node and access the linked list or a part of it cyclically in any direction.
The linked list in the Linux kernel is an excellent design. The linked list is used in the kernel, so it is best to use these existing linked list interfaces in your code, blocking the trend.
Next, let's take a look at the functions provided by the linked list in the Linux kernel.
First, the linked list struct is defined in the header file <Linux/list. h>. The format is simple:
Struct list_head {
Struct list_head * Next, Prev;
};
A list_head struct is meaningless. You usually need to embed it into your own struct:
Struct my_struct {
Struct list_head list;
Unsigned long dog;
Void * cat;
};
The linked list must be initialized before use. Because most elements are dynamically created (maybe this is why you need to use the linked list), the most common situation is to initialize the linked list at runtime.
Struct my_struct * p;
P-> dog = 0;
P-> cat = NULL;
INIT_LIST_HEAD (& p-> list );

Directly declare and initialize a static linked list:
Static LIST_HEAD (fox );
The preceding statement declares and initializes a static linked list named fox.
You don't need to submit it to any Members in the linked list. You just need to insert the linked list structure into your own data.
The operation linked list Kernel provides a set of functions to operate the linked list. All these functions use one or more list_head struct pointers for parameters. Because the functions are implemented in the form of inline functions in C language, their prototype is in the header file <linuxlist. h>.
Interestingly, the complexity of all these functions is O (1). That is to say, regardless of the linked list size of these function operations, regardless of the amount of parameters they get, they are all completed at a constant time.
1. Add a node to the linked list: After the given Node
List_add (struct list_head * New, struct list_head * head)
2. Add a node to the linked list: before the given Node
List_add_tail (struct list_head * New, struct list_head * head)
3. delete a node from the linked list:
Lsit_del (struct list_head * entry)
Manually release the entry struct.
4. delete a node from the linked list and reinitialize it.
Lsit_del_init (struct list_head * entry)
5. Move the node from one linked list to another:
List_move (struct list_head * List, struct list_head * head)
List_move_tail (struct list_head * list, struct list_head * head)
6. Check whether the linked list is empty:
Lsit_empty (struct list_head * head)
If the specified linked list is empty, this function returns a non-0 value. Otherwise, 0 is returned.
7. merge two linked lists
List_splice (struct list_head * list, struct list_head * head)
List_splice_init (struct list_head * list, struct list_head * head)
If you have obtained the next and prev pointers, you can use the internal operation function to save the time for getting the pointer. The internal function and the external function have the same name, but the first two underscores are added.
Traversal chain table:
The kernel provides us with a set of very useful interfaces to traverse the chain tables, but their complexity is O (n), and n is the number of elements in the linked list. The list_for_each () macro is used to traverse a chain table. It has two parameters: the first is used to point to the current item, and the second is the linked list to be traversed. However, it only obtains the lsit_head pointer, what I need is to insert the struct of list_head. The list_entry () macro can help us to have three parameters. One isPointer to a given linked list elementOne is the reference of the struct type embedded in the linked list, and the other isName of the linked list member in the structUsage:
Struct list_head * p;
Struct my_struct * my;
List_for_each (p, & mine-> List ){
My = list_entry (p, struct my_struct, list );
}
There are also some macros: list_for_each_prev () list_for_each_safe () can be selected
The last macro can only be used to prevent linked list deletion. To prevent concurrent access to the actual linked list data, other locks should be used.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.