1. 程式人生 > >連結串列的c語言實現以及根據linux核心中連結串列的實現過程

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

方式二:

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