¡¡¡¡Ò»¡¢ Á´±íÊý¾Ý½á¹¹¼ò½é
¡¡¡¡Á´±íÊÇÒ»ÖÖ³£ÓõÄ×éÖ¯ÓÐÐòÊý¾ÝµÄÊý¾Ý½á¹¹£¬Ëüͨ¹ýÖ¸Õ뽫һϵÁÐÊý¾Ý½ÚµãÁ¬½Ó³ÉÒ»ÌõÊý¾ÝÁ´£¬ÊÇÏßÐÔ±íµÄÒ»ÖÖÖØҪʵÏÖ·½Ê½¡£Ïà¶ÔÓÚÊý×飬Á´±í¾ßÓиüºÃµÄ¶¯Ì¬ÐÔ£¬½¨Á¢Á´±íʱÎÞÐèÔ¤ÏÈÖªµÀÊý¾Ý×ÜÁ¿£¬¿ÉÒÔËæ»ú·ÖÅä¿Õ¼ä£¬¿ÉÒÔ¸ßЧµØÔÚÁ´±íÖеÄÈÎÒâλÖÃʵʱ²åÈë»òɾ³ýÊý¾Ý¡£Á´±íµÄ¿ªÏúÖ÷ÒªÊÇ·ÃÎʵÄ˳ÐòÐÔºÍ×éÖ¯Á´µÄ¿Õ¼äËðʧ¡£
¡¡¡¡Í¨³£Á´±íÊý¾Ý½á¹¹ÖÁÉÙÓ¦°üº¬Á½¸öÓò£ºÊý¾ÝÓòºÍÖ¸ÕëÓò£¬Êý¾ÝÓòÓÃÓÚ´æ´¢Êý¾Ý£¬Ö¸ÕëÓòÓÃÓÚ½¨Á¢ÓëÏÂÒ»¸ö½ÚµãµÄÁªÏµ¡£°´ÕÕÖ¸ÕëÓòµÄ×éÖ¯ÒÔ¼°¸÷¸ö½ÚµãÖ®¼äµÄÁªÏµÐÎʽ£¬Á´±íÓÖ¿ÉÒÔ·ÖΪµ¥Á´±í¡¢Ë«Á´±í¡¢Ñ»·Á´±íµÈ¶àÖÖÀàÐÍ£¬ÏÂÃæ·Ö±ð¸ø³öÕ⼸Àà³£¼ûÁ´±íÀàÐ͵ÄʾÒâͼ£º
¡¡¡¡1. µ¥Á´±í
¡¡¡¡µ¥Á´±íÊÇ×î¼òµ¥µÄÒ»ÀàÁ´±í£¬ËüµÄÌصãÊǽöÓÐÒ»¸öÖ¸ÕëÓòÖ¸Ïòºó¼Ì½Úµã£¨next£©£¬Òò´Ë£¬¶Ôµ¥Á´±íµÄ±éÀúÖ»ÄÜ´ÓÍ·ÖÁβ£¨Í¨³£ÊÇ NULL ¿ÕÖ¸Õ룩˳Ðò½øÐС£
¡¡¡¡2. Ë«Á´±í
¡¡¡¡Í¨¹ýÉè¼ÆÇ°ÇýºÍºó¼ÌÁ½¸öÖ¸ÕëÓò£¬Ë«Á´±í¿ÉÒÔ´ÓÁ½¸ö·½Ïò±éÀú£¬ÕâÊÇËüÇø±ðÓÚµ¥Á´±íµÄµØ·½¡£Èç¹û´òÂÒÇ°Çý¡¢ºó¼ÌµÄÒÀÀµ¹Øϵ£¬¾Í¿ÉÒÔ¹¹³É"¶þ²æÊ÷"£»Èç¹ûÔÙÈÃÊ×½ÚµãµÄÇ°ÇýÖ¸ÏòÁ´±íβ½Úµã¡¢Î²½ÚµãµÄºó¼ÌÖ¸ÏòÊ׽ڵ㣨Èçͼ2ÖÐÐéÏß²¿·Ö£©£¬¾Í¹¹³ÉÁËÑ»·Á´±í£»Èç¹ûÉè¼Æ¸ü¶àµÄÖ¸ÕëÓò£¬¾Í¿ÉÒÔ¹¹³É¸÷ÖÖ¸´ÔÓµÄÊ÷×´Êý¾Ý½á¹¹¡£
¡¡¡¡3. Ñ»·Á´±í
¡¡¡¡Ñ»·Á´±íµÄÌصãÊÇβ½ÚµãµÄºó¼ÌÖ¸ÏòÊ׽ڵ㡣ǰÃæÒѾ¸ø³öÁËË«Ñ»·Á´±íµÄʾÒâͼ£¬ËüµÄÌصãÊÇ´ÓÈÎÒâÒ»¸ö½Úµã³ö·¢£¬ÑØÁ½¸ö·½ÏòµÄÈκÎÒ»¸ö£¬¶¼ÄÜÕÒµ½Á´±íÖеÄÈÎÒâÒ»¸öÊý¾Ý¡£Èç¹ûÈ¥µôÇ°ÇýÖ¸Õ룬¾ÍÊǵ¥Ñ»·Á´±í¡£
¡¡¡¡ÔÚLinuxÄÚºËÖÐʹÓÃÁË´óÁ¿µÄÁ´±í½á¹¹À´×éÖ¯Êý¾Ý£¬°üÀ¨É豸ÁбíÒÔ¼°¸÷ÖÖ¹¦ÄÜÄ£¿éÖеÄÊý¾Ý×éÖ¯¡£ÕâЩÁ´±í´ó¶à²ÉÓÃÔÚ[include/linux/list.h]ʵÏÖµÄÒ»¸öÏ൱¾«²ÊµÄÁ´±íÊý¾Ý½á¹¹¡£±¾Îĵĺó¼Ì²¿·Ö¾Í½«Í¨¹ýʾÀýÏêϸ½éÉÜÕâÒ»Êý¾Ý½á¹¹µÄ×éÖ¯ºÍʹÓá£
¡¡¡¡¶þ¡¢ Linux 2.6 ÄÚºËÁ´±íÊý¾Ý½á¹¹µÄʵÏÖ
¡¡¡¡¾¡¹ÜÕâÀïʹÓÃ2.6ÄÚºË×÷Ϊ½²½âµÄ»ù´¡£¬µ«Êµ¼ÊÉÏ 2.4 ÄÚºËÖеÄÁ´±í½á¹¹ºÍ 2.6 ²¢Ã»ÓÐʲôÇø±ð¡£²»Í¬Ö®´¦ÔÚÓÚ 2.6 À©³äÁËÁ½ÖÖÁ´±íÊý¾Ý½á¹¹£ºÁ´±íµÄ¶Á¿½±´¸üУ¨rcu£©ºÍ HASH Á´±í£¨hlist£©¡£ÕâÁ½ÖÖÀ©Õ¹¶¼ÊÇ»ùÓÚ×î»ù±¾µÄ list ½á¹¹£¬Òò´Ë£¬±¾ÎÄÖ÷Òª½éÉÜ»ù±¾Á´±í½á¹¹£¬È»ºóÔÙ¼òÒª½éÉÜһϠrcu ºÍ hlist¡£
¡¡¡¡Á´±íÊý¾Ý½á¹¹µÄ¶¨ÒåºÜ¼òµ¥£¨½ÚÑ¡×Ô [include/linux/list.h]£¬ÒÔÏÂËùÓдúÂ룬³ý·Ç¼ÓÒÔ˵Ã÷£¬ÆäÓà¾ùÈ¡×Ô¸ÃÎļþ£©£º
[code]struct list_head { struct list_head *next, *prev; };[/code]
wangyoubang ÓÚ 2009-07-22 15:49:44·¢±í:
ÔÚÊÕ²ØÁË Ð»ÁË
wangyoubang ÓÚ 2009-07-22 15:48:57·¢±í:
ÕâЩûѧºÃ ÏÖÔÚÔÚѧһ±é
balini ÓÚ 2009-07-22 15:09:02·¢±í:
ѧϰÁË
coolbg ÓÚ 2006-10-16 10:05:35·¢±í:
¡¡¡¡3. ±éÀú
¡¡¡¡±éÀúÊÇÁ´±í×î¾³£µÄ²Ù×÷Ö®Ò»£¬ÎªÁË·½±ãºËÐÄÓ¦ÓñéÀúÁ´±í£¬Linux Á´±í½«±éÀú²Ù×÷³éÏó³É¼¸¸öºê¡£ÔÚ½éÉܱéÀúºê֮ǰ£¬ÎÒÃÇÏÈ¿´¿´ÈçºÎ´ÓÁ´±íÖзÃÎʵ½ÎÒÃÇÕæÕýÐèÒªµÄÊý¾ÝÏî¡£
¡¡¡¡a) ÓÉÁ´±í½Úµãµ½Êý¾ÝÏî±äÁ¿
¡¡¡¡ÎÒÃÇÖªµÀ£¬Linux Á´±íÖнö±£´æÁËÊý¾ÝÏî½á¹¹ÖÐ list_head ³ÉÔ±±äÁ¿µÄµØÖ·£¬ÄÇôÎÒÃÇÈçºÎͨ¹ýÕâ¸ö list_head ³ÉÔ±·ÃÎʵ½×÷ΪËüµÄËùÓÐÕߵĽڵãÊý¾ÝÄØ£¿Linux Ϊ´ËÌṩÁËÒ»¸ö list_entry(ptr,type,member) ºê£¬ÆäÖÐptrÊÇÖ¸Ïò¸ÃÊý¾ÝÖÐ list_head ³ÉÔ±µÄÖ¸Õ룬Ҳ¾ÍÊÇ´æ´¢ÔÚÁ´±íÖеĵØÖ·Öµ£¬type ÊÇÊý¾ÝÏîµÄÀàÐÍ£¬member ÔòÊÇÊý¾ÝÏîÀàÐͶ¨ÒåÖÐ list_head ³ÉÔ±µÄ±äÁ¿Ãû£¬ÀýÈ磬ÎÒÃÇÒª·ÃÎÊ nf_sockopts Á´±íÖÐÊ׸ö nf_sockopt_ops ±äÁ¿£¬ÔòÈç´Ëµ÷Óãº
[code]¡¡list_entry(nf_sockopts->next, struct nf_sockopt_ops, list);[/code]
¡¡¡¡
¡¡¡¡ÕâÀï "list" ÕýÊÇ nf_sockopt_ops ½á¹¹Öж¨ÒåµÄÓÃÓÚÁ´±í²Ù×÷µÄ½Úµã³ÉÔ±±äÁ¿Ãû¡£
coolbg ÓÚ 2006-10-16 10:05:04·¢±í:
¡¡¡¡list_head ½á¹¹°üº¬Á½¸öÖ¸Ïò list_head ½á¹¹µÄÖ¸Õë prev ºÍ next£¬Óɴ˿ɼû£¬Äں˵ÄÁ´±í¾ß±¸Ë«Á´±í¹¦ÄÜ£¬Êµ¼ÊÉÏ£¬Í¨³£Ëü¶¼×éÖ¯³ÉË«Ñ»·Á´±í¡£
¡¡¡¡ºÍµÚÒ»½Ú½éÉܵÄË«Á´±í½á¹¹Ä£ÐͲ»Í¬£¬ÕâÀïµÄ list_head ûÓÐÊý¾ÝÓò¡£ÔÚ Linux ÄÚºËÁ´±íÖУ¬²»ÊÇÔÚÁ´±í½á¹¹Öаüº¬Êý¾Ý£¬¶øÊÇÔÚÊý¾Ý½á¹¹Öаüº¬Á´±í½Úµã¡£
¡¡¡¡ÔÚÊý¾Ý½á¹¹¿Î±¾ÖУ¬Á´±íµÄ¾µä¶¨Ò巽ʽͨ³£ÊÇÕâÑùµÄ£¨ÒÔµ¥Á´±íΪÀý£©£º
[code]struct list_node { struct list_node *next; ElemType data; };[/code]
¡¡¡¡ÒòΪ ElemType µÄÔµ¹Ê£¬¶ÔÿһÖÖÊý¾ÝÏîÀàÐͶ¼ÐèÒª¶¨Òå¸÷×ÔµÄÁ´±í½á¹¹¡£ÓоÑéµÄ C++ ³ÌÐòÔ±Ó¦¸ÃÖªµÀ£¬±ê׼ģ°å¿âÖÐµÄ ²ÉÓõÄÊÇ C++ Template£¬ÀûÓÃÄ£°å³éÏó³öºÍÊý¾ÝÏîÀàÐÍÎ޹صÄÁ´±í²Ù×÷½Ó¿Ú¡£
¡¡¡¡ÔÚ Linux ÄÚºËÁ´±íÖУ¬ÐèÒªÓÃÁ´±í×éÖ¯ÆðÀ´µÄÊý¾Ýͨ³£»á°üº¬Ò»¸ö struct list_head ³ÉÔ±£¬ÀýÈçÔÚ [include/linux/netfilter.h] Öж¨ÒåÁËÒ»¸ö nf_sockopt_ops ½á¹¹À´ÃèÊö Netfilter ΪijһÐÒé×å×¼±¸µÄ getsockopt/setsockopt ½Ó¿Ú£¬ÆäÖоÍÓÐÒ»¸ö£¨struct list_head list£©³ÉÔ±£¬¸÷¸öÐÒé×åµÄ nf_sockopt_ops ½á¹¹¶¼Í¨¹ýÕâ¸ö list ³ÉÔ±×éÖ¯ÔÚÒ»¸öÁ´±íÖУ¬±íÍ·ÊǶ¨ÒåÔÚ [net/core/netfilter.c] ÖÐµÄ nf_sockopts£¨struct list_head£©¡£´ÓÏÂͼÖÐÎÒÃÇ¿ÉÒÔ¿´µ½£¬ÕâÖÖͨÓõÄÁ´±í½á¹¹±ÜÃâÁËΪÿ¸öÊý¾ÝÏîÀàÐͶ¨Òå×Ô¼ºµÄÁ´±íµÄÂé·³¡£ Linux µÄ¼ò½ÝʵÓᢲ»ÇóÍêÃÀºÍ±ê×¼µÄ·ç¸ñ£¬ÔÚÕâÀïÌåÏÖµÃÏ൱³ä·Ö¡£
¡¡¡¡Èý¡¢ Á´±í²Ù×÷½Ó¿Ú
¡¡¡¡1. ÉùÃ÷ºÍ³õʼ»¯
¡¡¡¡Êµ¼ÊÉÏ Linux Ö»¶¨ÒåÁËÁ´±í½Úµã£¬²¢Ã»ÓÐרÃŶ¨ÒåÁ´±íÍ·£¬ÄÇôһ¸öÁ´±í½á¹¹ÊÇÈçºÎ½¨Á¢ÆðÀ´µÄÄØ£¿ÈÃÎÒÃÇÀ´¿´¿´ LIST_HEAD() Õâ¸öºê£º
[code]#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name)[/code]
¡¡¡¡
¡¡¡¡µ±ÎÒÃÇÓà LIST_HEAD(nf_sockopts) ÉùÃ÷Ò»¸öÃûΪ nf_sockopts µÄÁ´±íͷʱ£¬ËüµÄ next¡¢prev Ö¸Õ붼³õʼ»¯ÎªÖ¸Ïò×Ô¼º£¬ÕâÑù£¬ÎÒÃǾÍÓÐÁËÒ»¸ö¿ÕÁ´±í£¬ÒòΪ Linux ÓÃÍ·Ö¸ÕëµÄ next ÊÇ·ñÖ¸Ïò×Ô¼ºÀ´ÅжÏÁ´±íÊÇ·ñΪ¿Õ£º
[code]¡¡static inline int list_empty(const struct list_head *head)
{ return head->next == head; }[/code]
¡¡
¡¡¡¡³ýÁËÓà LIST_HEAD() ºêÔÚÉùÃ÷µÄʱºò³õʼ»¯Ò»¸öÁ´±íÒÔÍ⣬Linux »¹ÌṩÁËÒ»¸ö INIT_LIST_HEAD ºêÓÃÓÚÔËÐÐʱ³õʼ»¯Á´±í£º
[code]#define INIT_LIST_HEAD(ptr) do { (ptr)->next = (ptr);
(ptr)->prev = (ptr); } while (0)[/code]
¡¡
¡¡¡¡ÎÒÃÇÓà INIT_LIST_HEAD(&nf_sockopts) À´Ê¹ÓÃËü¡£
¡¡¡¡2. ²åÈë/ɾ³ý/ºÏ²¢
¡¡¡¡a) ²åÈë
¡¡¡¡¶ÔÁ´±íµÄ²åÈë²Ù×÷ÓÐÁ½ÖÖ£ºÔÚ±íÍ·²åÈëºÍÔÚ±íβ²åÈë¡£LinuxΪ´ËÌṩÁËÁ½¸ö½Ó¿Ú£º
[code]¡¡static inline void list_add
(struct list_head *new, struct list_head *head);
static inline void list_add_tail
(struct list_head *new, struct list_head *head);[/code]
¡¡¡¡
¡¡¡¡ÒòΪ Linux Á´±íÊÇÑ»·±í£¬ÇÒ±íÍ·µÄ next¡¢prev ·Ö±ðÖ¸ÏòÁ´±íÖеĵÚÒ»¸öºÍ×îÄ©Ò»¸ö½Úµã£¬ËùÒÔ£¬list_add ºÍ list_add_tail µÄÇø±ð²¢²»´ó£¬Êµ¼ÊÉÏ£¬Linux ·Ö±ðÓÃ
[code]¡¡¡¡__list_add(new, head, head->next);[/code]
¡¡
¡¡¡¡ºÍ
[code]¡¡__list_add(new, head->prev, head);[/code]
¡¡
¡¡¡¡À´ÊµÏÖÁ½¸ö½Ó¿Ú£¬¿É¼û£¬ÔÚ±íÍ·²åÈëÊDzåÈëÔÚ head Ö®ºó£¬¶øÔÚ±íβ²åÈëÊDzåÈëÔÚ head->prev Ö®ºó¡£
¡¡¡¡¼ÙÉèÓÐÒ»¸öРnf_sockopt_ops ½á¹¹±äÁ¿ new_sockopt ÐèÒªÌí¼Óµ½ nf_sockopts Á´±íÍ·£¬ÎÒÃÇÓ¦µ±ÕâÑù²Ù×÷£º
[code]¡¡list_add(&new_sockopt.list, &nf_sockopts);[/code]
¡¡¡¡
¡¡¡¡´ÓÕâÀïÎÒÃÇ¿´³ö£¬nf_sockopts Á´±íÖмǼµÄ²¢²»ÊÇ new_sockopt µÄµØÖ·£¬¶øÊÇÆäÖÐµÄ list ÔªËصĵØÖ·¡£ÈçºÎͨ¹ýÁ´±í·ÃÎʵ½ new_sockopt ÄØ£¿ÏÂÃæ»áÓÐÏêϸ½éÉÜ¡£
¡¡¡¡b) ɾ³ý
[code]¡¡static inline void list_del(struct list_head *entry);[/code]
¡¡
¡¡¡¡µ±ÎÒÃÇÐèҪɾ³ý nf_sockopts Á´±íÖÐÌí¼ÓµÄ new_sockopt Ïîʱ£¬ÎÒÃÇÕâô²Ù×÷£º
[code]list_del(&new_sockopt.list);[/code]
¡¡¡¡±»ÌÞ³ýÏÂÀ´µÄ new_sockopt.list£¬prev¡¢next Ö¸Õë·Ö±ð±»ÉèΪ LIST_POSITION2 ºÍ LIST_POSITION1 Á½¸öÌØÊâÖµ£¬ÕâÑùÉèÖÃÊÇΪÁ˱£Ö¤²»ÔÚÁ´±íÖеĽڵãÏî²»¿É·ÃÎÊ--¶Ô LIST_POSITION1 ºÍ LIST_POSITION2 µÄ·ÃÎʶ¼½«ÒýÆðÒ³¹ÊÕÏ¡£ÓëÖ®Ïà¶ÔÓ¦£¬ list_del_init() º¯Êý½«½Úµã´ÓÁ´±íÖнâÏÂÀ´Ö®ºó£¬µ÷Óà LIST_INIT_HEAD() ½«½ÚµãÖÃΪ¿ÕÁ´×´Ì¬¡£
¡¡¡¡c) °áÒÆ
¡¡¡¡Linux ÌṩÁ˽«Ô±¾ÊôÓÚÒ»¸öÁ´±íµÄ½ÚµãÒƶ¯µ½ÁíÒ»¸öÁ´±íµÄ²Ù×÷£¬²¢¸ù¾Ý²åÈëµ½ÐÂÁ´±íµÄλÖ÷ÖΪÁ½Àࣺ
[code]¡¡static inline void list_move
(struct list_head *list, struct list_head *head);
static inline void list_move_tail
(struct list_head *list, struct list_head *head);[/code]
¡¡
¡¡¡¡ÀýÈç list_move(&new_sockopt.list,&nf_sockopts) »á°Ñ new_sockopt ´ÓËüËùÔÚµÄÁ´±íÉÏɾ³ý£¬²¢½«ÆäÔÙÁ´Èë nf_sockopts µÄ±íÍ·¡£
¡¡¡¡d) ºÏ²¢
¡¡¡¡³ýÁËÕë¶Ô½ÚµãµÄ²åÈ롢ɾ³ý²Ù×÷£¬Linux Á´±í»¹ÌṩÁËÕû¸öÁ´±íµÄ²åÈ빦ÄÜ£º
[code]static inline void list_splice
(struct list_head *list, struct list_head *head);[/code]
¡¡¡¡
¡¡¡¡¼ÙÉ赱ǰÓÐÁ½¸öÁ´±í£¬±íÍ··Ö±ðÊÇ list1 ºÍ list2£¨¶¼ÊÇ struct list_head ±äÁ¿£©£¬µ±µ÷Óà list_splice(&list1,&list2) ʱ£¬Ö»Òª list1 ·Ç¿Õ£¬list1 Á´±íµÄÄÚÈݽ«±»¹Ò½ÓÔÚ list2 Á´±íÉÏ£¬Î»ÓÚ list2 ºÍ list2.next£¨Ô list2 ±íµÄµÚÒ»¸ö½Úµã£©Ö®¼ä¡£Ð list2 Á´±í½«ÒÔÔ list1 ±íµÄµÚÒ»¸ö½ÚµãΪÊ׽ڵ㣬¶øβ½Úµã²»±ä¡£Èçͼ£¨Ðé¼ýͷΪnextÖ¸Õ룩£º
¡¡¡¡µ± list1 ±»¹Ò½Óµ½ list2 Ö®ºó£¬×÷ΪԱíÍ·Ö¸ÕëµÄ list1 µÄ next¡¢prev ÈÔȻָÏòÔÀ´µÄ½Úµã£¬ÎªÁ˱ÜÃâÒýÆð»ìÂÒ£¬Linux ÌṩÁËÒ»¸ö list_splice_init() º¯Êý£º
[code]static inline void list_splice_init
(struct list_head *list, struct list_head *head);[/code]
¡¡¡¡
¡¡¡¡¸Ãº¯ÊýÔÚ½« list ºÏ²¢µ½ head Á´±íµÄ»ù´¡ÉÏ£¬µ÷Óà INIT_LIST_HEAD(list) ½« list ÉèÖÃΪ¿ÕÁ´¡£