linux进程链表,linux中链表_队列等的基本原理以及操作以及堆栈

内核版本为:2.4.10

等待队列

相关结构体:

DECLARE_WAITQUEUE(wait, current); // 定义一个等待队列,和当前进程挂钩

#define DECLARE_WAITQUEUE(name, tsk) wait_queue_t name = __WAITQUEUE_INITIALIZER(name, tsk)

#define __WAITQUEUE_INITIALIZER(name, tsk) { \

task: tsk, \

task_list: { NULL, NULL }, \

// 等待队列

struct __wait_queue {

unsigned int flags;

#define WQ_FLAG_EXCLUSIVE 0x01

struct task_struct *task;

struct list_head task_list;

#if WAITQUEUE_DEBUG

long __magic;

long __waker;

#endif

};

typedef struct __wait_queue wait_queue_t;

// 等待队列头

struct __wait_queue_head {

wq_lock_t lock; // 读写锁

struct list_head task_list;

#if WAITQUEUE_DEBUG

long __magic;

long __creator;

#endif

};

typedef struct __wait_queue_head wait_queue_head_t;

// 信号量

struct semaphore {

atomic_t count;

int sleepers;

wait_queue_head_t wait;

#if WAITQUEUE_DEBUG

long __magic;

#endif

};

函数操作:

将等待队列挂入等待队列头

add_wait_queue_exclusive(&sem->wait, &wait); // void add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t * wait)

wait->flags &= ~WQ_FLAG_EXCLUSIVE;

__add_wait_queue_tail(q, wait); // (&sem->wait, &wait) //

list_add_tail(&new->task_list, &head->task_list); // &wait->task_list挂入sem->wait->task_list尾部

将等待队列从队列头上卸载

remove_wait_queue(&sem->wait, &wait);

__remove_wait_queue(q, wait); // (&sem->wait, &wait)

list_del(&old->task_list); // wait->task_list

唤醒等待队列头

wake_up(&sem->wait); // 唤醒信号量上面的进程

链表相关的操作:

结构体

struct list_head {

struct list_head *next, *prev;

};

初始化

1 结构体方式

#define LIST_HEAD_INIT(name) {&(name), &(name)}

#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name)

2 指针方式

#define INIT_LIST_HEAD(ptr) do {     \

(ptr)->next = (ptr); (ptr)->prev = (ptr); \

} while (0)

向链表里面插入元素

void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next)

{

prev->next = new;

new->prev = prev;

new->next = next;

next->prev = new;

}

// 把new插入head后面,插入表头

void list_add(struct list_head *new, sturct list_head *head)

{

__list_add(new, head, head->next);

}

// 把new插入head前面,插入表尾

void list_add_tail(struct list_head *new, struct list_head *head)

{

__list_add(new, head->prev, head);

}

// 从链表里删除元素

void __list_del(struct list_head *prev, struct list_head *next)

{

prev->next = next;

next->prev = prev;

}

void list_del(struct list_head *entry)

{

__list_del(entry->prev, entry->next); // 出队列

entry->prev = entry->next = NULL; // 重新初始化entry

}

// 删除元素并初始化

void list_del_init(struct list_head *entry)

{

__list_del(entry->prev, entry->next);

INIT_LIST_HEAD(entry);

}

// 判断链表队列是否为空

int list_empty(struct list_head *head)

{

return (head->next == head);

}

// 链表拼接

// 把list链表接到head后面,实现链表合并,------> 链表队列的合并以及堆栈的原理!

void list_splice(struct list_head *list, struct list_head *head)

{

struct list_head *first = list->next;

if (list != first)

{

struct list_head *last = list->prev;

struct list_head *at = head->next;

head->next = first;

first->prev = head;

last->next = at;

at->prev = last;

}

}

// 通过指针获取到宿主结构,基本思想为通过list_head插槽的地址减去对应在宿主结构的偏移量,然后进行强制类型转换!

#define list_entry(ptr, type, member)   \

(type *)((char *)ptr - (unsigned long)(&(((type *)0)->member)))

以上基本上为内核里面的代码,可以基于上面的代码实现堆栈!

typedef structnode {intnum;structlist_head node;

}tNode,*ptNode;

ptNode ptTmp;

tNode NODE;struct list_head *glist;void stack_print(void)

{inti, inum;struct list_head *ptlisthead;for (i = 0; i < 5; i++) {

scanf("%d", &inum);

ptTmp= (ptNode)malloc(sizeof(structnode));if (NULL ==ptTmp) {

printf("malloc error\n");return;

}

ptTmp->num =inum;

list_add(&(ptTmp->node), glist);

}

printf("stack out:\n");for (i = 0; i < 5; i++) {

ptlisthead= (glist->next);

ptTmp= (ptNode)list_entry(ptlisthead, structnode, node);

list_del(ptlisthead);

printf("%d\n", ptTmp->num);free(ptTmp);

}

}void queue_print(void)

{inti, inum;struct list_head *ptlisthead;for (i = 0; i < 5; i++) {

scanf("%d", &inum);

ptTmp= (ptNode)malloc(sizeof(structnode));if (NULL ==ptTmp) {

printf("malloc error\n");return;

}

ptTmp->num =inum;

list_add_tail(&(ptTmp->node), glist);

}

printf("queue out:\n");for (i = 0; i < 5; i++) {

ptlisthead= (glist->next);

ptTmp= (ptNode)list_entry(ptlisthead, structnode, node);

list_del(ptlisthead);

printf("%d\n", ptTmp->num);free(ptTmp);

}

}int main(int argc, char **argv)

{

glist= (struct list_head *)malloc(sizeof(structlist_head));

if (NULL == glist)

return -1;

INIT_LIST_HEAD(glist);

stack_print();

printf("\nenter 5 int for queue\n");

queue_print();

free(glist);return 0;

}

编译生成可执行文件a.out。执行结果为:

[root@localhost]# ./a.out

1

2

3

4

5

stack out:

5

4

3

2

1

enter 5 int for queue

1

2

3

4

5

queue out:

1

2

3

4

5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值