链表的c语言实现以及根据linux内核中链表的实现过程
2012-09-23 20:36
369 查看
链表,就是用一组任意的存储单元存储线性表元素的一种数据结构。链表又分为单链表、双向链表和循环链表等。
下面代码是链表的两种实现方式,其中方式一就是按照数据结构书中对链表的实现过程,而方式二是根据linux内核中关于链表的实现。两者的最大区别是方式一中数据是存储在链表结构中的,而方式二中,是在数据结构中包含链表结构的。个人更倾向于第二种实现方法。
链表在内核中的使用例子,在驱动层我们可以建立一个链表实现数据的收发:比如当出现硬件中断时,我们将接收到的数据存储在链表中,并唤醒一个等待队列;而应用层通过阻塞的方式调用ioctl,当链表为空时,则进行睡眠操作,当出现一个唤醒操作时则读取链表中存在的消息,并返回给应用层,让应用层再进行相应的处理。这是链表在驱动层中的一个应用例子。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdint.h>
#include<signal.h>
#include<pthread.h>
#include<semaphore.h>
#include<unistd.h>
typedefintpri_spin_t;
pri_spin_tspin_flag=1;
#defineMAX_READ_ENTRY10
typedefstruct_listp
{
struct_listp*next;
struct_listp*prev;
intdata;
}LISTP;
voidpri_spin_lock(pri_spin_t*flag)
{
while(1)
{
if(*flag)
{
*flag=0;
return;
}
}
}
voidpri_spin_unlock(pri_spin_t*flag)
{
*flag=1;
}
voidinit_list_head(LISTP*listp)
{
listp->next=listp;
listp->prev=listp;
}
voidlist_add(LISTP*list_head,LISTP*listp)
{
list_head->next->prev=listp;
listp->next=list_head->next;
listp->prev=list_head;
list_head->next=listp;
}
voidlist_add_tail(LISTP*list_head,LISTP*listp)
{
list_head->prev->next=listp;
listp->prev=list_head->prev;
listp->next=list_head;
list_head->prev=listp;
}
intlist_is_empty(LISTP*list_head)
{
return(list_head->next==list_head);
}
voidlist_del(LISTP*listp)
{
LISTP*prev;
LISTP*next;
prev=listp->prev;
next=listp->next;
prev->next=next;
next->prev=prev;
listp->next=listp;
listp->prev=listp;
}
voidfree_list(LISTP*list_head)
{
LISTP*pos=NULL;
pos=list_head->next;
while(pos!=list_head)
{
list_del(pos);
free(pos);
pos=list_head->next;
printf("free\n");
}
if((list_head->next==list_head->prev)&&(list_head->next==list_head))
{
printf("listempty\n");
}
list_head->next=NULL;
list_head->prev=NULL;
free(list_head);
}
intadd_data(intdata,LISTP*list_head)
{
LISTP*listp=NULL;
listp=(LISTP*)malloc(sizeof(LISTP));
if(listp==NULL)
{
printf("%s:Cannotgetmemory\n",__FUNCTION__);
return-1;
}
listp->data=data;
list_add(list_head,listp);
}
intadd_data_tail(intdata,LISTP*list_head)
{
LISTP*listp=NULL;
listp=(LISTP*)malloc(sizeof(LISTP));
if(listp==NULL)
{
printf("%s:Cannotgetmemory\n",__FUNCTION__);
return-1;
}
listp->data=data;
list_add_tail(list_head,listp);
}
voidprint_data(LISTP*list_head)
{
intdata;
LISTP*pos;
if(list_is_empty(list_head))
{
printf("listheadisempty\n");
return;
}
for(pos=list_head->next;pos!=list_head;pos=pos->next)
{
if(pos)
{
if(pos->next==list_head)
printf("%d\n",pos->data);
else
printf("%d\t",pos->data);
}
}
}
voidread_data(LISTP*list_head,intnum)
{
intdata;
LISTP*entry;
if(list_is_empty(list_head))
{
printf("listheadisempty\n");
return;
}
if(num>MAX_READ_ENTRY)
{
num=MAX_READ_ENTRY;
}
printf("READMESSAGEIS:\n");
for(entry=list_head->next;(entry!=list_head)&&(num>0);entry=list_head->next)
{
printf("%d\t",entry->data);
list_del(entry);
entry->next=NULL;
entry->prev=NULL;
free(entry);
num--;
printf("\n");
}
void*send_message_pth1(void*arg)
{
inti=0;
while(1)
{
pri_spin_lock(&spin_flag);
add_data_tail(i,(LISTP*)arg);
printf("-----INSEND_MESSAGE_PTHREAD1-----\n");
pri_spin_unlock(&spin_flag);
i++;
sleep(2);
}
}
void*send_message_pth2(void*arg)
{
inti=0;
while(1)
{
pri_spin_lock(&spin_flag);
add_data_tail(i,(LISTP*)arg);
printf("-----INSEND_MESSAGE_PTHREAD2-----\n");
pri_spin_unlock(&spin_flag);
i++;
sleep(2);
}
}
void*print_message_pth(void*arg)
{
while(1)
{
pri_spin_lock(&spin_flag);
printf("-----INPRINT_MESSAGE_PTHREAD-----\n");
print_data((LISTP*)arg);
pri_spin_unlock(&spin_flag);
sleep(2);
}
}
void*read_message_pth(void*arg)
{
intnum=5;
while(1)
{
pri_spin_lock(&spin_flag);
printf("-----INREAD_MESSAGE_PTH-----\n");
read_data((LISTP*)arg,num);
pri_spin_unlock(&spin_flag);
sleep(6);
}
}
intmain()
{
inti=0;
LISTP*list_head=NULL;
pthread_tpth1;
pthread_tpth2;
pthread_tpth3;
pthread_tpth4;
list_head=(LISTP*)malloc(sizeof(LISTP));
if(list_head==NULL)
{
printf("Cannotgetmemory\n");
return-1;
}
init_list_head(list_head);
/*storedataintolist_head*/
for(i=0;i<10;i++)
{
pri_spin_lock(&spin_flag);
add_data_tail(i,list_head);
pri_spin_unlock(&spin_flag);
}
if(pthread_create(&pth1,NULL,(void*)send_message_pth1,list_head))
{
printf("createpthreadfailed\n");
return-1;
}
if(pthread_create(&pth2,NULL,(void*)send_message_pth2,list_head))
{
printf("createpthreadfailed\n");
return-1;
}
if(pthread_create(&pth3,NULL,(void*)print_message_pth,list_head))
{
printf("createpthreadfailed\n");
return-1;
}
if(pthread_create(&pth4,NULL,(void*)read_message_pth,list_head))
{
printf("createpthreadfailed\n");
return-1;
}
while(1);
return0;
}
方式二:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdint.h>
#include<signal.h>
#include<pthread.h>
#include<semaphore.h>
#include<unistd.h>
typedefintpri_spin_t;
#defineMAX_READ_ENTRY10
#defineGET_ADDR_BY_OFFSET(ptr,type,member)((type*)((char*)ptr-(uint32_t)(&(((type*)0)->member))))
typedefstruct_listp
{
struct_listp*next;
struct_listp*prev;
}LISTP;
typedefstruct_list_msg
{
intdata;
LISTPlist;
}LIST_MSG;
typedefstruct_module_struct
{
LISTPlist_head;
pri_spin_tspin_flag;
}MODULE_STRUCT;
voidpri_spin_lock(pri_spin_t*flag)
{
while(1)
{
if(*flag)
{
*flag=0;
return;
}
}
}
voidpri_spin_unlock(pri_spin_t*flag)
{
*flag=1;
}
voidinit_list_head(LISTP*listp)
{
listp->next=listp;
listp->prev=listp;
}
voidlist_add(LISTP*list_head,LISTP*listp)
{
list_head->next->prev=listp;
listp->next=list_head->next;
listp->prev=list_head;
list_head->next=listp;
}
voidlist_add_tail(LISTP*list_head,LISTP*listp)
{
list_head->prev->next=listp;
listp->prev=list_head->prev;
listp->next=list_head;
list_head->prev=listp;
}
intlist_is_empty(LISTP*list_head)
{
return(list_head->next==list_head);
}
voidlist_del(LISTP*listp)
{
LISTP*prev;
LISTP*next;
prev=listp->prev;
next=listp->next;
prev->next=next;
next->prev=prev;
listp->next=listp;
listp->prev=listp;
}
voidfree_list(LISTP*list_head)
{
LISTP*pos=NULL;
pos=list_head->next;
while(pos!=list_head)
{
list_del(pos);
free(pos);
pos=list_head->next;
printf("free\n");
}
if((list_head->next==list_head->prev)&&(list_head->next==list_head))
{
printf("listempty\n");
}
list_head->next=NULL;
list_head->prev=NULL;
free(list_head);
}
intadd_data(intdata,LISTP*list_head)
{
LIST_MSG*list_message=NULL;
list_message=(LIST_MSG*)malloc(sizeof(LIST_MSG));
if(list_message==NULL)
{
printf("%s:Cannotgetmemory\n",__FUNCTION__);
return-1;
}
init_list_head(&(list_message->list));
list_message->data=data;
list_add(list_head,&(list_message->list));
return0;
}
intadd_data_tail(intdata,LISTP*list_head)
{
LIST_MSG*list_message=NULL;
list_message=(LIST_MSG*)malloc(sizeof(LIST_MSG));
if(list_message==NULL)
{
printf("%s:Cannotgetmemory\n",__FUNCTION__);
return-1;
}
init_list_head(&(list_message->list));
list_message->data=data;
list_add_tail(list_head,&(list_message->list));
return0;
}
voidprint_data(LISTP*list_head)
{
intdata;
LISTP*pos;
LIST_MSG*message;
if(list_is_empty(list_head))
{
printf("listheadisempty\n");
return;
}
for(pos=list_head->next;pos!=list_head;pos=pos->next)
{
if(pos)
{
message=GET_ADDR_BY_OFFSET(pos,LIST_MSG,list);
if(message)
{
printf("%d\t",message->data);
}
}
}
printf("\n");
}
voidread_data(LISTP*list_head,intnum)
{
intdata;
LISTP*entry;
LIST_MSG*message;
if(list_is_empty(list_head))
{
printf("listheadisempty\n");
return;
}
if(num>MAX_READ_ENTRY)
{
num=MAX_READ_ENTRY;
}
printf("READMESSAGEIS:\n");
for(entry=list_head->next;(entry!=list_head)&&(num>0);entry=list_head->next)
{
message=GET_ADDR_BY_OFFSET(entry,LIST_MSG,list);
if(message)
{
printf("%d\t",message->data);
list_del(&(message->list));
free(message);
num--;
}
}
printf("\n");
}
void*send_message_pth1(void*arg)
{
inti=0;
MODULE_STRUCT*main_data;
main_data=(MODULE_STRUCT*)arg;
while(1)
{
pri_spin_lock(&(main_data->spin_flag));
add_data_tail(i,&(main_data->list_head));
printf("-----INSEND_MESSAGE_PTHREAD1-----\n");
pri_spin_unlock(&(main_data->spin_flag));
i++;
sleep(2);
}
}
void*send_message_pth2(void*arg)
{
inti=0;
MODULE_STRUCT*main_data;
main_data=(MODULE_STRUCT*)arg;
while(1)
{
pri_spin_lock(&(main_data->spin_flag));
add_data_tail(i,&(main_data->list_head));
printf("-----INSEND_MESSAGE_PTHREAD2-----\n");
pri_spin_unlock(&(main_data->spin_flag));
i++;
sleep(2);
}
}
void*print_message_pth(void*arg)
{
MODULE_STRUCT*main_data;
main_data=(MODULE_STRUCT*)arg;
while(1)
{
pri_spin_lock(&(main_data->spin_flag));
printf("-----INPRINT_MESSAGE_PTHREAD-----\n");
print_data(&(main_data->list_head));
pri_spin_unlock(&(main_data->spin_flag));
sleep(2);
}
}
void*read_message_pth(void*arg)
{
intnum=5;
MODULE_STRUCT*main_data;
main_data=(MODULE_STRUCT*)arg;
while(1)
{
pri_spin_lock(&(main_data->spin_flag));
printf("-----INREAD_MESSAGE_PTH-----\n");
read_data(&(main_data->list_head),num);
pri_spin_unlock(&(main_data->spin_flag));
sleep(3);
}
}
intmain()
{
inti=0;
MODULE_STRUCTmain_data;
pthread_tpth1;
pthread_tpth2;
pthread_tpth3;
pthread_tpth4;
main_data.spin_flag=1;
init_list_head(&(main_data.list_head));
for(i=0;i<10;i++)
{
pri_spin_lock(&(main_data.spin_flag));
add_data_tail(i,&(main_data.list_head));
pri_spin_unlock(&(main_data.spin_flag));
}
if(pthread_create(&pth1,NULL,(void*)send_message_pth1,(void*)&main_data))
{
printf("createpthreadfailed\n");
return-1;
}
if(pthread_create(&pth2,NULL,(void*)send_message_pth2,(void*)&main_data))
{
printf("createpthreadfailed\n");
return-1;
}
if(pthread_create(&pth3,NULL,(void*)print_message_pth,(void*)&main_data))
{
printf("createpthreadfailed\n");
return-1;
}
if(pthread_create(&pth4,NULL,(void*)read_message_pth,(void*)&main_data))
{
printf("createpthreadfailed\n");
return-1;
}
while(1);
return0;
}
相关文章推荐
- 链表的c语言实现以及根据linux内核中链表的实现过程
- linux下GCC编译环境中二叉树遍历、C语言实现以及调试过程中段错误
- C语言单向动态链表程序,实现链表的建立,合并,重新排序,链表元素的插入与删除,以及根据元素成员的值进行元素删除。
- Linux 实现自动安装服务组件以及优化内核参数 (转)
- 队列的C语言实现(通过内核链表)
- 改进式PID控制以及C语言实现过程
- Linux环境用C语言实现读取配置文件来区分产品的多个版本以及多个功能
- linux中C语言实现双向循环链表
- 双向循环链表linux中C语言实现双向循环链表
- linux 内核启动过程以及挂载android 根文件系统的过程
- Linux内核--网络栈实现分析(二)--数据包的传递过程(上)
- Linux下的C语言编程——链表实现通讯录
- (原创)linux内核进程调度以及定时器实现机制
- linux路由内核实现分析(三)---路由查找过程
- Linux下的C语言编程——用链表实现栈操作
- Linux下安装MyEclipse和Tomcat服务器详解,以及我安装过程中所出现的问题以及解决办法,并实现一个web小程序
- Linux 实现自动安装服务组件以及优化内核参数
- linux路由内核实现分析(三)---路由查找过程
- Linux grep命令分析以及C语言版本的实现
- linux 2.4内核中双向链表的实现/include/linux/list.h