链表的c语言实现以及根据linux内核中链表的实现过程

转自 : http://blog.csdn.net/lickylin/article/details/8010618


链表,就是用一组任意的存储单元存储线性表元素的一种数据结构。链表又分为单链表、双向链表和循环链表等。

下面代码是链表的两种实现方式,其中方式一就是按照数据结构书中对链表的实现过程,而方式二是根据linux内核中关于链表的实现。两者的最大区别是方式一中数据是存储在链表结构中的,而方式二中,是在数据结构中包含链表结构的。个人更倾向于第二种实现方法。

链表在内核中的使用例子,在驱动层我们可以建立一个链表实现数据的收发:比如当出现硬件中断时,我们将接收到的数据存储在链表中,并唤醒一个等待队列;而应用层通过阻塞的方式调用ioctl,当链表为空时,则进行睡眠操作,当出现一个唤醒操作时则读取链表中存在的消息,并返回给应用层,让应用层再进行相应的处理。这是链表在驱动层中的一个应用例子。

[html]  view plain  copy  print ?
  1. #include<stdio.h>  
  2. #include<stdlib.h>  
  3. #include<string.h>  
  4. #include<stdint.h>  
  5. #include<signal.h>  
  6. #include<pthread.h>  
  7. #include<semaphore.h>  
  8. #include<unistd.h>  
  9. typedef int pri_spin_t;  
  10. pri_spin_t spin_flag = 1;  
  11. #define MAX_READ_ENTRY 10  
  12. typedef struct _listp  
  13. {  
  14.     struct _listp *next;  
  15.     struct _listp *prev;  
  16.     int data;  
  17. }LISTP;  
  18.   
  19. void pri_spin_lock(pri_spin_t *flag)  
  20. {  
  21.     while(1)  
  22.     {  
  23.         if(*flag)  
  24.         {  
  25.             *flag = 0;  
  26.             return;  
  27.         }  
  28.     }  
  29.       
  30. }  
  31.   
  32. void pri_spin_unlock(pri_spin_t *flag)  
  33. {  
  34.     *flag = 1;  
  35. }  
  36.   
  37.   
  38.   
  39. void init_list_head(LISTP *listp)  
  40. {  
  41.     listp->next = listp;  
  42.     listp->prev = listp;  
  43. }  
  44.   
  45. void list_add(LISTP *list_head, LISTP *listp)  
  46. {  
  47.   
  48.     list_head->next->prev = listp;  
  49.     listp->next = list_head->next;  
  50.     listp->prev = list_head;  
  51.     list_head->next = listp;  
  52. }  
  53. void list_add_tail(LISTP *list_head, LISTP *listp)  
  54. {  
  55.     list_head->prev->next = listp;  
  56.     listp->prev = list_head->prev;  
  57.     listp->next=list_head;  
  58.     list_head->prev = listp;  
  59.   
  60. }  
  61.   
  62. int list_is_empty(LISTP *list_head)  
  63. {  
  64.     return (list_head->next == list_head);  
  65. }  
  66.   
  67. void list_del(LISTP *listp)  
  68. {  
  69.     LISTP *prev;  
  70.     LISTP *next;  
  71.     prev = listp->prev;  
  72.     next = listp->next;  
  73.     prev->next = next;  
  74.     next->prev = prev;  
  75.       
  76.     listp->next = listp;  
  77.     listp->prev = listp;  
  78. }  
  79. void free_list(LISTP *list_head)  
  80. {  
  81.     LISTP *pos = NULL;  
  82.     pos = list_head->next;  
  83.     while(pos != list_head)  
  84.     {  
  85.         list_del(pos);  
  86.             free(pos);  
  87.         pos = list_head->next;     
  88.         printf("free\n");  
  89.     }  
  90.       
  91.     if((list_head->next == list_head->prev)&&(list_head->next == list_head))  
  92.     {  
  93.         printf("list empty\n");  
  94.     }  
  95.     list_head->next = NULL;  
  96.     list_head->prev = NULL;  
  97.   
  98.     free(list_head);  
  99. }  
  100. int add_data(int data, LISTP *list_head)  
  101. {  
  102.     LISTP *listp = NULL;  
  103.   
  104.     listp = (LISTP *)malloc(sizeof(LISTP));  
  105.     if(listp == NULL)  
  106.     {  
  107.         printf("%s:Can not get memory\n", __FUNCTION__);  
  108.         return -1;  
  109.     }  
  110.   
  111.     listp->data = data;  
  112.     list_add(list_head, listp);  
  113.       
  114. }  
  115. int add_data_tail(int data, LISTP *list_head)  
  116. {  
  117.     LISTP *listp = NULL;  
  118.   
  119.     listp = (LISTP *)malloc(sizeof(LISTP));  
  120.     if(listp == NULL)  
  121.     {  
  122.         printf("%s:Can not get memory\n", __FUNCTION__);  
  123.         return -1;  
  124.     }  
  125.   
  126.     listp->data = data;  
  127.     list_add_tail(list_head, listp);  
  128.       
  129. }  
  130. void print_data(LISTP *list_head)  
  131. {     
  132.     int data;  
  133.     LISTP *pos;  
  134.   
  135.     if(list_is_empty(list_head))  
  136.     {  
  137.         printf("list head is empty\n");  
  138.         return;  
  139.     }  
  140.     for(pos = list_head->next; pos != list_head;pos = pos->next)  
  141.     {  
  142.         if(pos)  
  143.         {  
  144.             if(pos->next == list_head)  
  145.                 printf("%d\n", pos->data);  
  146.             else  
  147.                 printf("%d\t", pos->data);  
  148.         }  
  149.     }     
  150. }  
  151. void read_data(LISTP *list_head, int num)  
  152. {  
  153.     int data;  
  154.     LISTP *entry;  
  155.   
  156.     if(list_is_empty(list_head))  
  157.     {  
  158.         printf("list head is empty\n");  
  159.         return;  
  160.     }  
  161.       
  162.     if(num > MAX_READ_ENTRY)  
  163.     {  
  164.         num = MAX_READ_ENTRY;  
  165.     }  
  166.     printf("READ MESSAGE IS:\n");  
  167.     for(entry = list_head->next; (entry != list_head)&&(num > 0); entry = list_head->next)  
  168.     {  
  169.         printf("%d\t", entry->data);  
  170.         list_del(entry);  
  171.         entry->next = NULL;  
  172.         entry->prev = NULL;  
  173.         free(entry);  
  174.         num--;  
  175.       
  176.     printf("\n");     
  177. }  
  178.   
  179. void *send_message_pth1(void *arg)  
  180. {  
  181.     int i = 0;  
  182.     while(1)  
  183.     {  
  184.         pri_spin_lock(&spin_flag);    
  185.         add_data_tail(i, (LISTP *)arg);  
  186.         printf("-----IN SEND_MESSAGE_PTHREAD 1-----\n");  
  187.         pri_spin_unlock(&spin_flag);  
  188.         i++;  
  189.         sleep(2);     
  190.     }  
  191. }  
  192. void *send_message_pth2(void *arg)  
  193. {  
  194.     int i = 0;  
  195.     while(1)  
  196.     {  
  197.         pri_spin_lock(&spin_flag);    
  198.         add_data_tail(i, (LISTP *)arg);  
  199.                 printf("-----IN SEND_MESSAGE_PTHREAD 2-----\n");  
  200.                 pri_spin_unlock(&spin_flag);  
  201.         i++;  
  202.         sleep(2);     
  203.     }  
  204. }  
  205. void *print_message_pth(void *arg)  
  206. {  
  207.     while(1)  
  208.     {  
  209.   
  210.                 pri_spin_lock(&spin_flag);  
  211.                 printf("-----IN PRINT_MESSAGE_PTHREAD-----\n");  
  212.         print_data((LISTP *)arg);  
  213.         pri_spin_unlock(&spin_flag);  
  214.         sleep(2);  
  215.     }  
  216. }     
  217.   
  218. void *read_message_pth(void *arg)  
  219. {  
  220.     int num = 5;  
  221.       
  222.     while(1)  
  223.     {  
  224.         pri_spin_lock(&spin_flag);  
  225.         printf("-----IN READ_MESSAGE_PTH-----\n");  
  226.         read_data((LISTP *)arg, num);  
  227.         pri_spin_unlock(&spin_flag);  
  228.         sleep(6);  
  229.     }  
  230.       
  231. }  
  232. int main()  
  233. {  
  234.     int i = 0;  
  235.     LISTP *list_head = NULL;  
  236.     pthread_t pth1;  
  237.     pthread_t pth2;  
  238.     pthread_t pth3;  
  239.     pthread_t pth4;  
  240.     list_head = (LISTP *)malloc(sizeof(LISTP));  
  241.     if(list_head == NULL)  
  242.     {  
  243.         printf("Can not get memory\n");  
  244.         return -1;  
  245.     }  
  246.     init_list_head(list_head);  
  247.   
  248.     /*store data into list_head*/  
  249.     for(i = 0; i < 10; i ++)  
  250.     {  
  251.         pri_spin_lock(&spin_flag);  
  252.         add_data_tail(i, list_head);  
  253.         pri_spin_unlock(&spin_flag);  
  254.     }  
  255.   
  256.   
  257.     if(pthread_create(&pth1, NULL, (void *)send_message_pth1, list_head))  
  258.     {  
  259.         printf("create pthread failed\n");  
  260.         return -1;  
  261.     }  
  262.     if(pthread_create(&pth2, NULL, (void *)send_message_pth2, list_head))  
  263.     {  
  264.         printf("create pthread failed\n");  
  265.         return -1;  
  266.     }  
  267.     if(pthread_create(&pth3, NULL, (void *)print_message_pth, list_head))  
  268.     {  
  269.         printf("create pthread failed\n");  
  270.         return -1;  
  271.     }  
  272.     if(pthread_create(&pth4, NULL, (void *)read_message_pth, list_head))  
  273.     {  
  274.         printf("create pthread failed\n");  
  275.         return -1;  
  276.     }  
  277.     while(1);  
  278.     return 0;  
  279. }  


 

 

方式二:

[html]  view plain  copy  print ?
  1. #include<stdio.h>  
  2. #include<stdlib.h>  
  3. #include<string.h>  
  4. #include<stdint.h>  
  5. #include<signal.h>  
  6. #include<pthread.h>  
  7. #include<semaphore.h>  
  8. #include<unistd.h>  
  9. typedef int pri_spin_t;  
  10. #define MAX_READ_ENTRY 10  
  11. #define GET_ADDR_BY_OFFSET(ptr, type, member) ((type *)((char *)ptr - (uint32_t)(&(((type *)0)->member))))  
  12.   
  13. typedef struct _listp  
  14. {  
  15.     struct _listp *next;  
  16.     struct _listp *prev;  
  17. }LISTP;  
  18.   
  19. typedef struct _list_msg  
  20. {  
  21.     int data;  
  22.     LISTP list;  
  23. }LIST_MSG;  
  24.   
  25. typedef struct _module_struct  
  26. {  
  27.     LISTP list_head;  
  28.     pri_spin_t spin_flag;  
  29. }MODULE_STRUCT;  
  30.   
  31. void pri_spin_lock(pri_spin_t *flag)  
  32. {  
  33.     while(1)  
  34.     {  
  35.         if(*flag)  
  36.         {  
  37.             *flag = 0;  
  38.             return;  
  39.         }  
  40.     }  
  41.       
  42. }  
  43.   
  44. void pri_spin_unlock(pri_spin_t *flag)  
  45. {  
  46.     *flag = 1;  
  47. }  
  48.   
  49.   
  50.   
  51. void init_list_head(LISTP *listp)  
  52. {  
  53.     listp->next = listp;  
  54.     listp->prev = listp;  
  55. }  
  56.   
  57. void list_add(LISTP *list_head, LISTP *listp)  
  58. {  
  59.   
  60.     list_head->next->prev = listp;  
  61.     listp->next = list_head->next;  
  62.     listp->prev = list_head;  
  63.     list_head->next = listp;  
  64. }  
  65. void list_add_tail(LISTP *list_head, LISTP *listp)  
  66. {  
  67.     list_head->prev->next = listp;  
  68.     listp->prev = list_head->prev;  
  69.     listp->next=list_head;  
  70.     list_head->prev = listp;  
  71.   
  72. }  
  73.   
  74. int list_is_empty(LISTP *list_head)  
  75. {  
  76.     return (list_head->next == list_head);  
  77. }  
  78.   
  79. void list_del(LISTP *listp)  
  80. {  
  81.     LISTP *prev;  
  82.     LISTP *next;  
  83.     prev = listp->prev;  
  84.     next = listp->next;  
  85.     prev->next = next;  
  86.     next->prev = prev;  
  87.       
  88.     listp->next = listp;  
  89.     listp->prev = listp;  
  90. }  
  91. void free_list(LISTP *list_head)  
  92. {  
  93.     LISTP *pos = NULL;  
  94.     pos = list_head->next;  
  95.     while(pos != list_head)  
  96.     {  
  97.         list_del(pos);  
  98.             free(pos);  
  99.         pos = list_head->next;     
  100.         printf("free\n");  
  101.     }  
  102.       
  103.     if((list_head->next == list_head->prev)&&(list_head->next == list_head))  
  104.     {  
  105.         printf("list empty\n");  
  106.     }  
  107.     list_head->next = NULL;  
  108.     list_head->prev = NULL;  
  109.   
  110.     free(list_head);  
  111. }  
  112. int add_data(int data, LISTP *list_head)  
  113. {  
  114.     LIST_MSG *list_message = NULL;  
  115.   
  116.     list_message = (LIST_MSG *)malloc(sizeof(LIST_MSG));  
  117.     if(list_message == NULL)  
  118.     {  
  119.         printf("%s:Can not get memory\n", __FUNCTION__);  
  120.         return -1;  
  121.     }  
  122.   
  123.     init_list_head(&(list_message->list));  
  124.     list_message->data = data;  
  125.     list_add(list_head, &(list_message->list));  
  126.     return 0;     
  127. }  
  128. int add_data_tail(int data, LISTP *list_head)  
  129. {  
  130.     LIST_MSG *list_message = NULL;  
  131.   
  132.     list_message = (LIST_MSG *)malloc(sizeof(LIST_MSG));  
  133.     if(list_message == NULL)  
  134.     {  
  135.         printf("%s:Can not get memory\n", __FUNCTION__);  
  136.         return -1;  
  137.     }  
  138.     init_list_head(&(list_message->list));  
  139.       
  140.     list_message->data = data;  
  141.     list_add_tail(list_head, &(list_message->list));  
  142.     return 0;  
  143. }  
  144. void print_data(LISTP *list_head)  
  145. {     
  146.     int data;  
  147.     LISTP *pos;  
  148.     LIST_MSG *message;  
  149.   
  150.     if(list_is_empty(list_head))  
  151.     {  
  152.         printf("list head is empty\n");  
  153.         return;  
  154.     }  
  155.   
  156.   
  157.     for(pos = list_head->next; pos != list_head;pos = pos->next)  
  158.     {  
  159.         if(pos)  
  160.         {  
  161.             message = GET_ADDR_BY_OFFSET(pos, LIST_MSG, list);  
  162.             if(message)  
  163.             {  
  164.                 printf("%d\t", message->data);  
  165.             }  
  166.         }  
  167.     }     
  168.     printf("\n");  
  169.       
  170. }  
  171. void read_data(LISTP *list_head, int num)  
  172. {  
  173.     int data;  
  174.     LISTP *entry;  
  175.     LIST_MSG *message;  
  176.   
  177.     if(list_is_empty(list_head))  
  178.     {  
  179.         printf("list head is empty\n");  
  180.         return;  
  181.     }  
  182.   
  183.       
  184.     if(num > MAX_READ_ENTRY)  
  185.     {  
  186.         num = MAX_READ_ENTRY;  
  187.     }  
  188.   
  189.     printf("READ MESSAGE IS:\n");  
  190.   
  191.     for(entry = list_head->next; (entry != list_head)&&(num > 0); entry = list_head->next)  
  192.     {  
  193.   
  194.         message = GET_ADDR_BY_OFFSET(entry, LIST_MSG, list);  
  195.         if(message)  
  196.         {  
  197.             printf("%d\t", message->data);  
  198.             list_del(&(message->list));  
  199.             free(message);  
  200.             num--;  
  201.         }  
  202.     }  
  203.     printf("\n");     
  204. }  
  205.   
  206. void *send_message_pth1(void *arg)  
  207. {  
  208.     int i = 0;  
  209.         MODULE_STRUCT *main_data;  
  210.     main_data = (MODULE_STRUCT *)arg;     
  211.     while(1)  
  212.     {  
  213.         pri_spin_lock(&(main_data->spin_flag));  
  214.         add_data_tail(i, &(main_data->list_head));  
  215.         printf("-----IN SEND_MESSAGE_PTHREAD 1-----\n");  
  216.         pri_spin_unlock(&(main_data->spin_flag));  
  217.         i++;  
  218.         sleep(2);     
  219.     }  
  220. }  
  221. void *send_message_pth2(void *arg)  
  222. {  
  223.     int i = 0;  
  224.         MODULE_STRUCT *main_data;  
  225.     main_data = (MODULE_STRUCT *)arg;     
  226.     while(1)  
  227.     {  
  228.         pri_spin_lock(&(main_data->spin_flag));    
  229.         add_data_tail(i, &(main_data->list_head));  
  230.                 printf("-----IN SEND_MESSAGE_PTHREAD 2-----\n");  
  231.                 pri_spin_unlock(&(main_data->spin_flag));  
  232.         i++;  
  233.         sleep(2);     
  234.     }  
  235. }  
  236. void *print_message_pth(void *arg)  
  237. {  
  238.         MODULE_STRUCT *main_data;  
  239.     main_data = (MODULE_STRUCT *)arg;     
  240.     while(1)  
  241.     {  
  242.   
  243.                 pri_spin_lock(&(main_data->spin_flag));  
  244.                 printf("-----IN PRINT_MESSAGE_PTHREAD-----\n");  
  245.         print_data(&(main_data->list_head));  
  246.         pri_spin_unlock(&(main_data->spin_flag));  
  247.         sleep(2);  
  248.     }  
  249. }     
  250.   
  251. void *read_message_pth(void *arg)  
  252. {  
  253.     int num = 5;  
  254.         MODULE_STRUCT *main_data;  
  255.     main_data = (MODULE_STRUCT *)arg;     
  256.       
  257.     while(1)  
  258.     {  
  259.         pri_spin_lock(&(main_data->spin_flag));  
  260.         printf("-----IN READ_MESSAGE_PTH-----\n");  
  261.         read_data(&(main_data->list_head), num);  
  262.         pri_spin_unlock(&(main_data->spin_flag));  
  263.         sleep(3);  
  264.     }  
  265.       
  266. }  
  267. int main()  
  268. {  
  269.     int i = 0;  
  270.     MODULE_STRUCT main_data;  
  271.     pthread_t pth1;  
  272.     pthread_t pth2;  
  273.     pthread_t pth3;  
  274.     pthread_t pth4;  
  275.       
  276.     main_data.spin_flag = 1;  
  277.     init_list_head(&(main_data.list_head));  
  278.     for(i = 0; i < 10; i ++)  
  279.     {  
  280.         pri_spin_lock(&(main_data.spin_flag));  
  281.         add_data_tail(i, &(main_data.list_head));  
  282.         pri_spin_unlock(&(main_data.spin_flag));  
  283.     }  
  284.   
  285.     if(pthread_create(&pth1, NULL, (void *)send_message_pth1, (void *)&main_data))  
  286.     {  
  287.         printf("create pthread failed\n");  
  288.         return -1;  
  289.     }  
  290.     if(pthread_create(&pth2, NULL, (void *)send_message_pth2, (void *)&main_data))  
  291.     {  
  292.         printf("create pthread failed\n");  
  293.         return -1;  
  294.     }  
  295.     if(pthread_create(&pth3, NULL, (void *)print_message_pth, (void *)&main_data))  
  296.     {  
  297.         printf("create pthread failed\n");  
  298.         return -1;  
  299.     }  
  300.     if(pthread_create(&pth4, NULL, (void *)read_message_pth, (void *)&main_data))  
  301.     {  
  302.         printf("create pthread failed\n");  
  303.         return -1;  
  304.     }  
  305.     while(1);  
  306.     return 0;  
  307. }  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值