list_for_each_entry 및 list_for_each_entry_safe를 설명하십시오.


Answers

편집 : 미안 해요, 늦었어야, 나는 많은 오타를 만들었습니다.

그들은 순수한 재미입니다! :) 차이점은 list_for_each_entry 는 목록을 반복하면서 list_for_each_entry 를 삭제할 때 (물론 여분의 CPU 명령을 희생시키면서) 무언가를 삭제하면 중단 list_for_each_entry_safe 것입니다.

커널은 list.h에 singingly linked list 구현이 있음에도 불구하고 이중 연결리스트 (여러분이 이해하고 있다고 생각하는)에 정착했습니다. 귀하의 목록은 다음과 같습니다 :

struct list_head {
    struct list_head *next;
    struct list_head *prev;
};

동일한 구조체가 각 노드뿐만 아니라 목록의 "머리"에 사용된다는 점에 유의하십시오. 목록이 비어 있으면 머리의 next 멤버와 prev 멤버는 머리를 가리킨다. 따라서리스트를 반복하는 것은 머리의 next 멤버로 시작하여 그 노드를 호출하는 프로세스 일 뿐이며, prev 와 같은 주소 (멈출 때)가 아니면. 그렇지 않으면 본문이 호출되고 container_of() 매크로를 사용하여 실제 구조체에 대한 포인터를 가져 와서 사용할 수 있습니다. 그런 다음 for 의 3 번째 필드에서 다음 next 으로 넘어 next .

수정 : 아, 사과, 당신은 매개 변수에 대한 설명을 요청했습니다. 글쎄, 나는 누군가의 말을 듣기보다는 내가 너라면 직접 확인해 볼 것이다. 그 경우, 적어도 커널 API 문서 자체를 제안 할 것이고, 이는 링크 된 목록 라이브러리에 대해 적어도 존재합니다. 나는 그것을 통해 붉은 검정색 트리 라이브러리를 추가 할 패치 세트를 얻으려고하지만, 물건을 얻는 것은 상당한 과정이 될 수 있습니다.

또한 참고 : http://kernelnewbies.org/FAQ/LinkedLists

다음은 간단한 예입니다.

struct list_head my_actual_list;
struct my_struct {
    struct list_head node;
    /* some other members */
};

/* in a function body somewhere... */
struct list_head *i;
list_for_each(i, &my_actual_list) {
    struct my_struct *obj = list_entry(i, struct my_struct, node);
    // do something with obj
}

list_entrycontainer_of 의 별명입니다.

EDIT # 2

좋습니다, 의견에 대한 귀하의 질문에 대한 답변으로, 저는 제 대답을 확장 할 것입니다. C ++ STL 컨테이너, C 배열 등과 비교할 때 몇 가지 이상한 점이 있지만이 관념에 익숙해지면 꽤 자연 스러울 것입니다. 앞으로도이 구조체, 함수 및 매크로에 대한 정의를 직접 살펴보고 이해할 수 있도록 작성한 다음 질문하십시오.

먼저 목록의 각 노드는 struct list_head 유형의 구성원을 포함하는 struct list_head 이고 list struct list_head 유형의 목록입니다. 따라서 누가 컨테이너이고이 경우에 포함되어있는 사람은 단순히 사용 방법에 따라 다르지만 일반적으로이 멤버의 이름으로 표현됩니다. 이터레이터의 타입은 struct list_head * 이다. 다음은 예제이며 일반적인 함수와 매크로 호출을 동일한 코드로 대체합니다.

struct my_container {
    struct list_head list;
    int some_member;
    /* etc. */
};

struct my_obj {
    struct list_head node;
    int some_member;
    /* etc. */
};

void func() {
    struct my_container container;
    struct my_obj obj1, obj2;
    struct list_head *i;

    /* INIT_LIST_HEAD(&container.list); */
    container.list.next = &container.list;
    container.list.prev = &container.list;

    /* list_add_tail(&obj1.node); */
    container.list.prev = &obj1.node;
    obj1.node.next = &container.list;
    obj1.node.prev = &container.list;
    container.list.next = &obj1.node;

    /* list_add_tail(&obj2.node); */
    container.list.prev = &obj2.node;
    obj2.node.next = &container.list;
    obj2.node.prev = &obj1.node;
    obj1.node.next = &obj2.node;

    /* list_for_each(i, &container.list) { */
    for (i = container.list.next; i != &container.list; i = i->next) {
        struct my_obj *obj = list_entry(i, struct my_obj, node);
        /* do stuff */
    }

}

이제 읽으십시오! :)

Question

누구든지 list_for_each_entry 및 ... entry_safe 루프 작업을 리눅스에서 설명 할 수 있습니까? 그것은 같다.

list_for_each_entry(type *cursor, struct list_head *list, member)

list_for_each_entry_safe(type *cursor, type *next, struct list_head *list,member)

이 모든 매개 변수의 역할과 그 매개 변수가 목록을 통과하는 데 사용되는 방법은 무엇입니까?

ADVANCE에 감사드립니다.