尊龙凯时人生就是博

LinuxÄÚºËÖг£ÓõÄÊý¾Ý½á¹¹ºÍËã·¨

LinuxÄں˴úÂëÖÐÆÕ±éʹÓÃÁËÊý¾Ý½á¹¹ºÍËã·¨£¬ÆäÖÐ×î³£ÓõÄÁ½¸öÊÇÁ´±íºÍºìºÚÊ÷¡£

Á´±í

LinuxÄں˴úÂë´ó×ÚʹÓÃÁËÁ´±íÕâÖÖÊý¾Ý½á¹¹¡£Á´±íÊÇÔÚ½â¾öÊý×é²»¿É¶¯Ì¬À©Õ¹Õâ¸öȱÏݶø±¬·¢µÄÒ»ÖÖÊý¾Ý½á¹¹¡£Á´±íËù°üÀ¨µÄÔªËØ¿ÉÒÔ¶¯Ì¬½¨Éè²¢²åÈëºÍɾ³ý¡£Á´±íµÄÿ¸öÔªËض¼ÊÇÀëÉ¢´æ·ÅµÄ£¬Òò´Ë²»ÐèÒªÕ¼ÓÃÒ»Á¬µÄÄÚ´æ¡£Á´±íͨ³£ÓÉÈô¸É½Úµã×é³É£¬Ã¿¸ö½ÚµãµÄ½á¹¹¶¼ÊÇÒ»ÑùµÄ£¬ÓÉÓÐÓÃÊý¾ÝÇøºÍÖ¸ÕëÇøÁ½²¿·Ö×é³É¡£ÓÐÓÃÊý¾ÝÇøÓÃÀ´´æ´¢ÓÐÓÃÊý¾ÝÐÅÏ¢£¬¶øÖ¸ÕëÇøÓÃÀ´Ö¸ÏòÁ´±íµÄÇ°¼Ì½Úµã»òÕߺó¼Ì½Úµã¡£Òò´Ë£¬Á´±í¾ÍÊÇʹÓÃÖ¸Õ뽫¸÷¸ö½Úµã´®ÁªÆðÀ´µÄÒ»ÖÖ´æ´¢½á¹¹¡£

£¨1£©µ¥ÏòÁ´±í

µ¥ÏòÁ´±íµÄÖ¸ÕëÇøÖ»°üÀ¨Ò»¸öÖ¸ÏòÏÂÒ»¸ö½ÚµãµÄÖ¸Õ룬Òò´Ë»áÐγÉÒ»¸ö¼òµ¥Æ«ÏòµÄÁ´±í£¬ÈçÏ´úÂëËùʾ¡£

struct list {
    int data;   /*ÓÐÓÃÊý¾Ý*/
    struct list *next; /*Ö¸ÏòÏÂÒ»¸öÔªËصÄÖ¸Õë*/
};

µÇ¼ºó¸´ÖÆ

ÈçͼËùʾ£¬µ¥ÏòÁ´±í¾ßÓе¥ÏòÒƶ¯ÐÔ£¬Ò²¾ÍÊÇÖ»ÄÜ»á¼ûÄ¿½ñµÄ½ÚµãµÄºó¼Ì½Úµã£¬¶øÎÞ·¨»á¼ûÄ¿½ñ½ÚµãµÄÇ°¼Ì½Úµã£¬Òò´ËÔÚÏÖʵÏîÄ¿ÖÐÔËÓõýÏÁ¿ÉÙ¡£

µ¥ÏòÁ´ÌåÏÖÒâͼ

£¨2£©Ë«ÏòÁ´±í

ÈçͼËùʾ£¬Ë«ÏòÁ´±íºÍµ¥ÏòÁ´±íµÄÇø±ðÊÇÖ¸ÕëÇø°üÀ¨ÁËÁ½¸öÖ¸Õ룬һ¸öÖ¸ÏòÇ°¼Ì½Úµã£¬ÁíÒ»¸öÖ¸Ïòºó¼Ì½Úµã£¬ÈçÏ´úÂëËùʾ¡£

struct list {
    int data;   /*ÓÐÓÃÊý¾Ý*/
    struct list *next; /*Ö¸ÏòÏÂÒ»¸öÔªËصÄÖ¸Õë*/
    struct list *prev; /*Ö¸ÏòÉÏÒ»¸öÔªËصÄÖ¸Õë*/
};

µÇ¼ºó¸´ÖÆ

Ë«ÏòÁ´ÌåÏÖÒâͼ

£¨3£©LinuxÄÚºËÁ´±íʵÏÖ

µ¥ÏòÁ´±íºÍË«ÏòÁ´±íÔÚÏÖʵʹÓÃÖÐÓÐһЩ¾ÖÏÞÐÔ£¬ÈçÊý¾ÝÇø±ØÐèÊÇÀο¿Êý¾Ý£¬¶øÏÖʵÐèÇóÊǶàÖÖ¶àÑùµÄ¡£ÕâÖÖÒªÁìÎÞ·¨¹¹½¨Ò»Ì×ͨÓõÄÁ´±í£¬ÓÉÓÚÿ¸ö²î±ðµÄÊý¾ÝÇøÐèÒªÒ»Ì×Á´±í¡£Îª´Ë£¬LinuxÄں˰ÑËùÓÐÁ´±í²Ù×÷ÒªÁìµÄÅäºÏ²¿·ÖÌáÈ¡³öÀ´£¬°Ñ²î±ðµÄ²¿·ÖÁô¸ø´úÂë±à³ÌÕß×Ô¼ºÐÐÖ¹Öá£LinuxÄÚºËʵÏÖÁËÒ»Ì×´¿Á´±íµÄ·â×°£¬Á´±í½ÚµãÊý¾Ý½á¹¹Ö»ÓÐÖ¸ÕëÇø¶øûÓÐÊý¾ÝÇø£¬ÁíÍ⻹·â×°ÁËÖݪֲÙ×÷º¯Êý£¬È罨Éè½Úµãº¯Êý¡¢²åÈë½Úµãº¯Êý¡¢É¾³ý½Úµãº¯Êý¡¢±éÀú½Úµãº¯ÊýµÈ¡£

LinuxÄÚºËÁ´±íʹÓÃstruct list_headÊý¾Ý½á¹¹À´ÐÎò¡£

<include/linux/types.h>

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

µÇ¼ºó¸´ÖÆ

struct list_headÊý¾Ý½á¹¹²»°üÀ¨Á´±í½ÚµãµÄÊý¾ÝÇø£¬Í¨³£ÊÇǶÈëÆäËûÊý¾Ý½á¹¹£¬Èçstruct pageÊý¾Ý½á¹¹ÖÐǶÈëÁËÒ»¸ölruÁ´±í½Úµã£¬Í¨³£ÊÇ°ÑpageÊý¾Ý½á¹¹¹ÒÈëLRUÁ´±í¡£

<include/linux/mm_types.h>

struct page {
    ...
    struct list_head lru;
    ...
}

µÇ¼ºó¸´ÖÆ

Á´±íÍ·µÄ³õʼ»¯ÓÐÁ½ÖÖÒªÁ죬һÖÖÊǾ²Ì¬³õʼ»¯£¬ÁíÒ»ÖÖ¶¯Ì¬³õʼ»¯¡£

°ÑnextºÍprevÖ¸Õ붼³õʼ»¯²¢Ö¸Ïò×Ô¼º£¬ÕâÑù±ã³õʼ»¯ÁËÒ»¸ö´ø¶¯½ÚµãµÄ¿ÕÁ´±í¡£

<include/linux/list.h>

/*¾²Ì¬³õʼ»¯*/
#define LIST_HEAD_INIT(name) { &(name), &(name) }

#define LIST_HEAD(name) \
    struct list_head name = LIST_HEAD_INIT(name)

/*¶¯Ì¬³õʼ»¯*/
static inline void INIT_LIST_HEAD(struct list_head *list)
{
    list->next = list;
    list->prev = list;
}

µÇ¼ºó¸´ÖÆ

Ìí¼Ó½Úµãµ½Ò»¸öÁ´±íÖУ¬ÄÚºËÌṩÁ˼¸¸ö½Ó¿Úº¯Êý£¬Èçlist_add()ÊÇ°ÑÒ»¸ö½ÚµãÌí¼Óµ½±íÍ·£¬list_add_tail()ÊDzåÈë±íβ¡£

<include/linux/list.h>

void list_add(struct list_head *new, struct list_head *head)
list_add_tail(struct list_head *new, struct list_head *head)

µÇ¼ºó¸´ÖÆ

±éÀú½ÚµãµÄ½Ó¿Úº¯Êý¡£

#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)

µÇ¼ºó¸´ÖÆ

Õâ¸öºêÖ»ÊDZéÀúÒ»¸öÒ»¸ö½ÚµãµÄÄ¿½ñλÖã¬ÄÇôÔõÑù»ñÈ¡½Úµã×Ô¼ºµÄÊý¾Ý½á¹¹ÄØ£¿ÕâÀﻹÐèҪʹÓÃlist_entry()ºê¡£

#define list_entry(ptr, type, member) \
    container_of(ptr, type, member)
container_of()ºêµÄ½ç˵ÔÚkernel.hÍ·ÎļþÖС£
#define container_of(ptr, type, member) ({            \
    const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
    (type *)( (char *)__mptr - offsetof(type,member) );})

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

µÇ¼ºó¸´ÖÆ

ÆäÖÐoffsetof()ºêÊÇͨ¹ý°Ñ0µØµãת»»ÎªtypeÀàÐ͵ÄÖ¸Õ룬ȻºóÈ¥»ñÈ¡¸Ã½á¹¹ÌåÖÐmember³ÉÔ±µÄÖ¸Õ룬Ҳ¾ÍÊÇ»ñÈ¡ÁËmemberÔÚtype½á¹¹ÌåÖеÄÆ«ÒÆÁ¿¡£×îºóÓÃÖ¸Õëptr¼õÈ¥offset£¬¾Í»ñµÃtype½á¹¹ÌåµÄÕæʵµØµãÁË¡£

ÏÂÃæÊDZéÀúÁ´±íµÄÒ»¸öÀý×Ó¡£

<drivers/block/osdblk.c>

static ssize_t class_osdblk_list(struct class *c,
                struct class_attribute *attr,
                char *data)
{
    int n = 0;
    struct list_head *tmp;

    list_for_each(tmp, &osdblkdev_list) {
        struct osdblk_device *osdev;

        osdev = list_entry(tmp, struct osdblk_device, node);

        n += sprintf(data+n, "%d %d %llu %llu %s\n",
            osdev->id,
            osdev->major,
            osdev->obj.partition,
            osdev->obj.id,
            osdev->osd_path);
    }
    return n;
}

µÇ¼ºó¸´ÖÆ

ºìºÚÊ÷

ºìºÚÊ÷£¨Red Black Tree£©±»ÆÕ±éÓ¦ÓÃÔÚÄں˵ÄÄÚ´æÖÎÀíºÍÀú³Ìµ÷ÀíÖУ¬ÓÃÓÚ½«ÅÅÐòµÄÔªËØ×éÖ¯µ½Ê÷ÖС£ºìºÚÊ÷±»ÆÕ±éÓ¦ÓÃÔÚÅÌËã»ú¿ÆѧµÄ¸÷¸öÁìÓòÖУ¬ËüÔÚËÙÂʺÍʵÏÖÖØƯºóÖ®¼äÌṩһ¸öºÜºÃµÄƽºâ¡£

ºìºÚÊ÷ÊǾßÓÐÒÔÏÂÌØÕ÷µÄ¶þ²æÊ÷¡£

ÿ¸ö½Úµã»òºì»òºÚ¡£

ÿ¸öÒ¶½ÚµãÊÇÐþÉ«µÄ¡£

ÈôÊǽáµã¶¼ÊǺìÉ«£¬ÄÇôÁ½¸ö×Ó½áµã¶¼ÊÇÐþÉ«¡£

´ÓÒ»¸öÄÚ²¿½áµãµ½Ò¶½áµãµÄ¼òÆÓ·¾¶ÉÏ£¬¶ÔËùÓÐÒ¶½ÚµãÀ´Ëµ£¬ÐþÉ«½áµãµÄÊýÄ¿¶¼ÊÇÏàͬµÄ¡£

ºìºÚÊ÷µÄÒ»¸öÓŵãÊÇ£¬ËùÓÐÖ÷ÒªµÄ²Ù×÷£¨ÀýÈç²åÈ롢ɾ³ý¡¢ËÑË÷£©¶¼¿ÉÒÔÔÚO(log n)ʱ¼äÄÚÍê³É£¬nΪÊ÷ÖÐÔªËصÄÊýÄ¿¡£¾­µäµÄËã·¨½Ì¿ÆÊ鶼»á½â˵ºìºÚÊ÷µÄʵÏÖ£¬ÕâÀïÖ»ÊÇÁгöÒ»¸öÄÚºËÖÐʹÓúìºÚÊ÷µÄÀý×Ó£¬¹©¶ÁÕßÔÚÏÖʵµÄÇý¶¯ºÍÄں˱à³ÌÖвο¼¡£Õâ¸öÀý×Ó¿ÉÒÔÔÚÄں˴úÂëµÄdocumentation/Rbtree.txtÎļþÖÐÕÒµ½¡£

#include <linux/init.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/rbtree.h>

MODULE_AUTHOR("figo.zhang");
MODULE_DESCRIPTION(" ");
MODULE_LICENSE("GPL");

  struct mytype { 
     struct rb_node node;
     int key; 
};

/*ºìºÚÊ÷¸ù½Úµã*/
 struct rb_root mytree = RB_ROOT;
/*ƾ֤keyÀ´²éÕÒ½Úµã*/
struct mytype *my_search(struct rb_root *root, int new)
  {
     struct rb_node *node = root->rb_node;

     while (node) {
          struct mytype *data = container_of(node, struct mytype, node);

          if (data->key > new)
               node = node->rb_left;
          else if (data->key < new)
               node = node->rb_right;
          else
               return data;
     }
     return NULL;
  }

/*²åÈëÒ»¸öÔªËص½ºìºÚÊ÷ÖÐ*/
  int my_insert(struct rb_root *root, struct mytype *data)
  {
     struct rb_node **new = &(root->rb_node), *parent=NULL;

     /* Ñ°ÕÒ¿ÉÒÔÌí¼ÓнڵãµÄµØ·½ */
     while (*new) {
          struct mytype *this = container_of(*new, struct mytype, node);

          parent = *new;
          if (this->key > data->key)
               new = &((*new)->rb_left);
          else if (this->key < data->key) {
               new = &((*new)->rb_right);
          } else
               return -1;
     }

     /* Ìí¼ÓÒ»¸öнڵã */
     rb_link_node(&data->node, parent, new);
     rb_insert_color(&data->node, root);

     return 0;
  }

static int __init my_init(void)
{
     int i;
     struct mytype *data;
     struct rb_node *node;

     /*²åÈëÔªËØ*/
     for (i =0; i < 20; i+=2) {
          data = kmalloc(sizeof(struct mytype), GFP_KERNEL);
          data->key = i;
          my_insert(&mytree, data);
     }

     /*±éÀúºìºÚÊ÷£¬´òÓ¡ËùÓнڵãµÄkeyÖµ*/
      for (node = rb_first(&mytree); node; node = rb_next(node)) 
          printk("key=%d\n", rb_entry(node, struct mytype, node)->key);

     return 0;
}

static void __exit my_exit(void)
{
     struct mytype *data;
     struct rb_node *node;
     for (node = rb_first(&mytree); node; node = rb_next(node)) {
          data = rb_entry(node, struct mytype, node);
          if (data) {
                rb_erase(&data->node, &mytree);
                kfree(data);
          }
     }
}
module_init(my_init);
module_exit(my_exit);

µÇ¼ºó¸´ÖÆ

mytreeÊǺìºÚÊ÷µÄ¸ù½Úµã£¬my_insert()ʵÏÖ²åÈëÒ»¸öÔªËص½ºìºÚÊ÷ÖУ¬my_search()ƾ֤keyÀ´²éÕҽڵ㡣Äں˴ó×ÚʹÓúìºÚÊ÷£¬ÈçÐéÄâµØµã¿Õ¼äVMAµÄÖÎÀí¡£

ÎÞËø»·Ðλº³åÇø

Éú²úÕߺÍÏûºÄÕßÄ£×ÓÊÇÅÌËã»ú±à³ÌÖÐ×î³£¼ûµÄÒ»ÖÖÄ£×Ó¡£Éú²úÕß±¬·¢Êý¾Ý£¬¶øÏûºÄÕßÏûºÄÊý¾Ý£¬ÈçÒ»¸öÍøÂç×°±¸£¬Ó²¼þ×°±¸ÎüÊÕÍøÂç°ü£¬È»ºóÓ¦ÓóÌÐò¶ÁÈ¡ÍøÂç°ü¡ £»·Ðλº³åÇøÊÇʵÏÖÉú²úÕߺÍÏûºÄÕßÄ£×ӵľ­µäËã·¨¡ £»·Ðλº³åÇøͨ³£ÓÐÒ»¸ö¶ÁÖ¸ÕëºÍÒ»¸öдָÕë¡£¶ÁÖ¸ÕëÖ¸Ïò»·Ðλº³åÇøÖпɶÁµÄÊý¾Ý£¬Ð´Ö¸ÕëÖ¸Ïò»·Ðλº³åÇø¿ÉдµÄÊý¾Ý¡£Í¨¹ýÒƶ¯¶ÁÖ¸ÕëºÍдָÕëʵÏÖ»º³åÇøÊý¾ÝµÄ¶ÁÈ¡ºÍдÈë¡£

ÔÚLinuxÄÚºËÖУ¬KFIFOÊǽÓÄÉÎÞËø»·Ðλº³åÇøµÄʵÏÖ¡£FIFOµÄÈ«³ÆÊÇ¡°First In First Out¡±£¬¼´ÏȽøÏȳöµÄÊý¾Ý½á¹¹£¬Ëü½ÓÄÉ»·Ðλº³åÇøµÄÒªÁìÀ´ÊµÏÖ£¬²¢Ìṩһ¸öÎÞ½çÏßµÄ×Ö½ÚԼЧÀÍ¡£½ÓÄÉ»·Ðλº³åÇøµÄÀûÒæÊÇ£¬µ±Ò»¸öÊý¾ÝÔªËر»ÏûºÄÖ®ºó£¬ÆäÓàÊý¾ÝÔªËز»ÐèÒªÒƶ¯Æä´æ´¢Î»Ö㬴ӶøïÔÌ­¸´ÖÆ£¬Ìá¸ßЧÂÊ¡£

£¨1£©½¨ÉèKFIFO

ÔÚʹÓÃKFIFO֮ǰÐèÒª¾ÙÐгõʼ»¯£¬ÕâÀïÓо²Ì¬³õʼ»¯ºÍ¶¯Ì¬³õʼ»¯Á½ÖÖ·½·¨¡£

<include/linux/kfifo.h>

int kfifo_alloc(fifo, size, gfp_mask)

µÇ¼ºó¸´ÖÆ

¸Ãº¯Êý½¨Éè²¢·ÖÅÉÒ»¸ö¾ÞϸΪsizeµÄKFIFO»·Ðλº³åÇø¡£µÚÒ»¸ö²ÎÊýfifoÊÇÖ¸Ïò¸Ã»·Ðλº³åÇøµÄstruct kfifoÊý¾Ý½á¹¹ £»µÚ¶þ¸ö²ÎÊýsizeÊÇÖ¸¶¨»º³åÇøÔªËصÄÊýÄ¿ £»µÚÈý¸ö²ÎÊýgfp_maskÌåÏÖ·ÖÅÉKFIFOÔªËØʹÓõķÖÅÉÑÚÂë¡£

¾²Ì¬·ÖÅÉ¿ÉÒÔʹÓÃÈçϵĺê¡£

#define DEFINE_KFIFO(fifo, type, size)
#define INIT_KFIFO(fifo)

µÇ¼ºó¸´ÖÆ

£¨2£©ÈëÁÐ

°ÑÊý¾ÝдÈëKFIFO»·Ðλº³åÇø¿ÉÒÔʹÓÃkfifo_in()º¯Êý½Ó¿Ú¡£

int kfifo_in(fifo, buf, n)

µÇ¼ºó¸´ÖÆ

¸Ãº¯Êý°ÑbufÖ¸ÕëÖ¸ÏòµÄn¸öÊý¾Ý¸´ÖƵ½KFIFO»·Ðλº³åÇøÖС£µÚÒ»¸ö²ÎÊýfifoÖ¸µÄÊÇKFIFO»·Ðλº³åÇø £»µÚ¶þ¸ö²ÎÊýbufÖ¸ÏòÒª¸´ÖƵÄÊý¾ÝµÄbuffer £»µÚÈý¸öÊý¾ÝÊÇÒª¸´ÖÆÊý¾ÝÔªËصÄÊýÄ¿¡£

£¨3£©³öÁÐ

´ÓKFIFO»·Ðλº³åÇøÖÐÁгö»òÕßժȡÊý¾Ý¿ÉÒÔʹÓÃkfifo_out()º¯Êý½Ó¿Ú¡£

#define    kfifo_out(fifo, buf, n)

µÇ¼ºó¸´ÖÆ

¸Ãº¯ÊýÊÇ´ÓfifoÖ¸ÏòµÄ»·Ðλº³åÇøÖи´ÖÆn¸öÊý¾ÝÔªËص½bufÖ¸ÏòµÄ»º³åÇøÖС£ÈôÊÇKFIFO»·Ðλº³åÇøµÄÊý¾ÝÔªËØСÓÚn¸ö£¬ÄÇô¸´ÖƳöÈ¥µÄÊý¾ÝÔªËØСÓÚn¸ö¡£

£¨4£©»ñÈ¡»º³åÇø¾Þϸ

KFIFOÌṩÁ˼¸¸ö½Ó¿Úº¯ÊýÀ´ÅÌÎÊ»·Ðλº³åÇøµÄ״̬¡£

#define kfifo_size(fifo)
#define kfifo_len(fifo)
#define kfifo_is_empty(fifo)
#define kfifo_is_full(fifo)

µÇ¼ºó¸´ÖÆ

kfifo_size()ÓÃÀ´»ñÈ¡»·Ðλº³åÇøµÄ¾Þϸ£¬Ò²¾ÍÊÇ×î´ó¿ÉÒÔÈÝÄɼ¸¶à¸öÊý¾ÝÔªËØ¡£kfifo_len()ÓÃÀ´»ñÈ¡Ä¿½ñ»·Ðλº³åÇøÖÐÓм¸¶à¸öÓÐÓÃÊý¾ÝÔªËØ¡£kfifo_is_empty()Åжϻ·Ðλº³åÇøÊÇ·ñΪ¿Õ¡£kfifo_is_full()Åжϻ·Ðλº³åÇøÊÇ·ñΪÂú¡£

£¨5£©ÓëÓû§¿Õ¼äÊý¾Ý½»»¥

KFIFO»¹·â×°ÁËÁ½¸öº¯ÊýÓëÓû§¿Õ¼äÊý¾Ý½»»¥¡£

#define    kfifo_from_user(fifo, from, len, copied)
#define    kfifo_to_user(fifo, to, len, copied)

µÇ¼ºó¸´ÖÆ

kfifo_from_user()ÊÇ°ÑfromÖ¸ÏòµÄÓû§¿Õ¼äµÄlen¸öÊý¾ÝÔªËظ´ÖƵ½KFIFOÖУ¬×îºóÒ»¸ö²ÎÊýcopiedÌåÏÖÀֳɸ´ÖÆÁ˼¸¸öÊý¾ÝÔªËØ¡£

kfifo_to_user()ÔòÏà·´£¬°ÑKFIFOµÄÊý¾ÝÔªËظ´ÖƵ½Óû§¿Õ¼ä¡£ÕâÁ½¸öºêÍŽáÁËcopy_to_user()¡¢copy_from_user()ÒÔ¼°KFIFOµÄ»úÖÆ£¬¸øÇý¶¯¿ª·¢ÕßÌṩÁËÀû±ã¡£

ÒÔÉϾÍÊÇLinuxÄÚºËÖг£ÓõÄÊý¾Ý½á¹¹ºÍËã·¨µÄÏêϸÄÚÈÝ£¬¸ü¶àÇë¹Ø×¢±¾ÍøÄÚÆäËüÏà¹ØÎÄÕ£¡

ÃâÔð˵Ã÷£ºÒÔÉÏչʾÄÚÈÝȪԴÓÚÏàÖúýÌå¡¢ÆóÒµ»ú¹¹¡¢ÍøÓÑÌṩ»òÍøÂçÍøÂçÕûÀí£¬°æȨÕùÒéÓë±¾Õ¾Î޹أ¬ÎÄÕÂÉæ¼°¿´·¨Óë¿´·¨²»´ú±í尊龙凯时人生就是博ÂËÓÍ»úÍø¹Ù·½Ì¬¶È£¬Çë¶ÁÕß½ö×ö²Î¿¼¡£±¾ÎĽӴýתÔØ£¬×ªÔØÇë˵Ã÷À´ÓÉ¡£ÈôÄúÒÔΪ±¾ÎÄÇÖÕ¼ÁËÄúµÄ°æȨÐÅÏ¢£¬»òÄú·¢Ã÷¸ÃÄÚÈÝÓÐÈκÎÉæ¼°ÓÐÎ¥¹«µÂ¡¢Ã°·¸Ö´·¨µÈÎ¥·¨ÐÅÏ¢£¬ÇëÄúÁ¬Ã¦ÁªÏµ尊龙凯时人生就是博ʵʱÐÞÕý»òɾ³ý¡£

Ïà¹ØÐÂÎÅ

ÁªÏµ尊龙凯时人生就是博

18523999891

¿É΢ÐÅÔÚÏß×Éѯ

ÊÂÇéʱ¼ä£ºÖÜÒ»ÖÁÖÜÎ壬9:30-18:30£¬½ÚãåÈÕÐÝÏ¢

QR code
sitemap¡¢ÍøÕ¾µØͼ