Linuxカーネルには、プロセス、ファイル、モジュール、ページなど、二重にリンクされたリストを使用する必要のあるデータ構造が多数あります。二重リンクリストの従来の実装を採用する場合、これらのデータ構造のそれぞれのリンクリストを維持し、各リンクリストの挿入、削除、およびその他の操作機能を設計する必要があります。リンクリストを維持するために使用されるnextおよびprevポインターは、対応するタイプのオブジェクトを指すため、あるデータ構造のリンクリスト操作関数を使用して、他のデータ構造のリンクリストを操作することはできません。たとえば、スターとWebサーバーのタイムアウトのリンクリスト構造をそれぞれ定義する必要があります。
したがって、ソリューションをどのように使用するかは、リンクリストを共有することです。共有リンクリスト
の形式は次のようになり
ます。typedefstruct_DoubleLinkNode { struct _DoubleLinkNode * next; //次のノードのポインタフィールドstruct_DoubleLinkNode * prev; //前のノードのポインタフィールド} DbLinkNode; //リンクリストはハンギングポイントとしてデータに配置されます//クロックハンギングポイントtypedefstruct _ConnTimeout { int fd; time_t timeout; NodeList d;
} ConnTimeout;
//星を挂点typedefstruct
_START { int x; int y; int r; intステップ; int statu; NodeList d; }開始;
次のような小さなデモ:
/*
linux内核链表,使用的原因是因为通过一个链表就能实现对多个数结构体的删除
*/
#include<stdio.h>
#include<Windows.h>
#include<iostream>
#include<stdlib.h>
using namespace std;
//结构体指针
typedef struct _DoubleList{
_DoubleList *next;
_DoubleList *prev;
}DoubleList,NodeList;
//时钟挂点
typedef struct _ConnTimeout{
int fd;
time_t timeout;
NodeList d;
}ConnTimeout;
typedef struct _START{
int x;
int y;
int r;
int step;
int statu;
NodeList d;
}START;
//初始化链表
void init(DoubleList &L){
if(!&L) return ;
L.next = NULL;
L.prev = NULL;
}
//插入元素
void insertElemdata(DoubleList &L,DoubleList &node){
//找到最后一个结点
if(!&L||!&node) return ;
DoubleList *last = &L;
while(last->next) last = last->next;
node.next= NULL;
node.prev=last;
last->next = &node;
}
int main(void){
ConnTimeout *t = new ConnTimeout;
ConnTimeout *s =NULL;
init(t->d);
cout<<"请输入5个元素:"<<endl;
for(int i=0;i<5;i++){
//插入元素
s = new ConnTimeout;
cin>>s->fd;
insertElemdata(t->d,s->d);
}
//计算偏移值
int offset = offsetof(ConnTimeout,d);//获取偏移值
DoubleList * p = &(t->d);
while(p->next){
p=p->next;
ConnTimeout *ct = (ConnTimeout*)(size_t(p)-offset);
cout<<ct->fd<<"\t";
}
//销毁链表
printf("\n");
p =&(t->d);
//DoubleList *d;
while(p){
ConnTimeout *ct = (ConnTimeout*)(size_t(p)-offset);
cout<<"删除结点"<<ct->fd<<endl;
p=p->next;
delete ct;
}
system("pause");
return 0;
}