您的位置:首页 > 运维架构 > Linux

链表的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;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: