个人知识库 个人知识库
首页
关于
  • C语言
  • CPlusPlus
  • Linux
  • PHP
  • Nginx
  • MySQL
  • Redis
  • Docker
  • Kubernetes
  • SRS
阅读
常用工具
  • 分类
  • 标签
  • 归档
GitHub

Agnes001

坚持是一件很伟大的事业
首页
关于
  • C语言
  • CPlusPlus
  • Linux
  • PHP
  • Nginx
  • MySQL
  • Redis
  • Docker
  • Kubernetes
  • SRS
阅读
常用工具
  • 分类
  • 标签
  • 归档
GitHub
  • C语言

  • CPlusPlus

  • Lua技术栈

  • edoyun

  • 内存管理

  • 数据结构

  • 网络编程

  • Linux

  • 池化技术

    • 内存池

      • 队列
      • 内存池实现
  • 操作系统

  • python

  • 编程技术
  • 池化技术
Agnes001
2022-07-05

队列

libuv源码分析——1.queue:https://blog.csdn.net/AnitaSun/article/details/123968659

//queue.h

#ifndef QUEUE_H_
#define QUEUE_H_

#include <stddef.h>

typedef void *QUEUE[2];

//保证是左值,能进行赋值操作
#define QUEUE_NEXT(q)       (*(QUEUE **) &((*(q))[0]))
#define QUEUE_PREV(q)       (*(QUEUE **) &((*(q))[1]))
#define QUEUE_PREV_NEXT(q)  (QUEUE_NEXT(QUEUE_PREV(q)))
#define QUEUE_NEXT_PREV(q)  (QUEUE_PREV(QUEUE_NEXT(q)))

//offsetof,用来获取属性field在指定类型type的位置偏差,然后通过用ptr在内存中的地址减去该偏差就能得到对象在内存中的初始位置。
#define QUEUE_DATA(ptr, type, field)                                          \
  ((type *) ((char *) (ptr) - offsetof(type, field)))

//for循环不断取队列h中的元素,将其赋给q
#define QUEUE_FOREACH(q, h)                                                   \
  for ((q) = QUEUE_NEXT(h); (q) != (h); (q) = QUEUE_NEXT(q))

// 队列为空判断
#define QUEUE_EMPTY(q)                                                        \
  ((const QUEUE *) (q) == (const QUEUE *) QUEUE_NEXT(q))

// 获取队列头
#define QUEUE_HEAD(q)                                                         \
  (QUEUE_NEXT(q))

#define QUEUE_TAIL(q)                                                         \
  (QUEUE_PREV(q))

// 队列初始化
// do while包裹,让其变为一个整体,反例是放到if语句中
#define QUEUE_INIT(q)                                                         \
  do {                                                                        \
    QUEUE_NEXT(q) = (q);                                                      \
    QUEUE_PREV(q) = (q);                                                      \
  }                                                                           \
  while (0)

// 队列相加
#define QUEUE_ADD(h, n)                                                       \
  do {                                                                        \
    QUEUE_PREV_NEXT(h) = QUEUE_NEXT(n);                                       \
    QUEUE_NEXT_PREV(n) = QUEUE_PREV(h);                                       \
    QUEUE_PREV(h) = QUEUE_PREV(n);                                            \
    QUEUE_PREV_NEXT(h) = (h);                                                 \
  }                                                                           \
  while (0)

// 队列分割,将队列h以q为分割点进行分割,分割出来的新队列为n(n为分出来的双向循环链表的头结点)
#define QUEUE_SPLIT(h, q, n)                                                  \
  do {                                                                        \
    QUEUE_PREV(n) = QUEUE_PREV(h);                                            \
    QUEUE_PREV_NEXT(n) = (n);                                                 \
    QUEUE_NEXT(n) = (q);                                                      \
    QUEUE_PREV(h) = QUEUE_PREV(q);                                            \
    QUEUE_PREV_NEXT(h) = (h);                                                 \
    QUEUE_PREV(q) = (n);                                                      \
  }                                                                           \
  while (0)


// 队列移动,将队列h移动到n队里中
#define QUEUE_MOVE(h, n)                                                      \
  do {                                                                        \
    if (QUEUE_EMPTY(h))                                                       \
      QUEUE_INIT(n);                                                          \
    else {                                                                    \
      QUEUE* q = QUEUE_HEAD(h);                                               \
      QUEUE_SPLIT(h, q, n);                                                   \
    }                                                                         \
  }                                                                           \
  while (0)

// 向队列头插入节点
#define QUEUE_INSERT_HEAD(h, q)                                               \
  do {                                                                        \
    QUEUE_NEXT(q) = QUEUE_NEXT(h);                                            \
    QUEUE_PREV(q) = (h);                                                      \
    QUEUE_NEXT_PREV(q) = (q);                                                 \
    QUEUE_NEXT(h) = (q);                                                      \
  }                                                                           \
  while (0)

// 向队列尾插入节点
// 将元素q加入到队列h的尾部
#define QUEUE_INSERT_TAIL(h, q)                                               \
  do {                                                                        \
    QUEUE_NEXT(q) = (h);                                                      \
    QUEUE_PREV(q) = QUEUE_PREV(h);                                            \
    QUEUE_PREV_NEXT(q) = (q);                                                 \
    QUEUE_PREV(h) = (q);                                                      \
  }                                                                           \
  while (0)

// 队列删除
#define QUEUE_REMOVE(q)                                                       \
  do {                                                                        \
    QUEUE_PREV_NEXT(q) = QUEUE_NEXT(q);                                       \
    QUEUE_NEXT_PREV(q) = QUEUE_PREV(q);                                       \
  }                                                                           \
  while (0)

#endif /* QUEUE_H_ */

示例代码

#include <stdio.h>
#include "queue.h" // 引入队列

// 定义一个结构Work类型的struct类型
typedef struct {
  int index;
  QUEUE q;
} Work;

// 输出Work类型数据
void printWork(Work* work) {
  printf("work->index:%i\n", work->index);
}

int main() {
  // 定义队列的头节点
  QUEUE start;
  QUEUE_INIT(&start);

  // 创建10个Work对象
  int num = 10;
  Work works[num];

  for(int i = 0; i < num; ++i) {
    // 给每个work队形的index属性赋值
    works[i].index = i;

    // 将每个work对象插入到队列中
    QUEUE_INSERT_TAIL(&start, &works[i].q);
  }

  QUEUE* tmpQ;
  Work* tmpWork;
  
  // 遍历队列
  QUEUE_FOREACH(tmpQ, &start){
    // 根据队列指针返回work对象
    tmpWork = QUEUE_DATA(tmpQ, Work, q);
    // 输出队列数据
    printWork(tmpWork);
  }

  return 0;
}
编辑此页
linux内核多线程
内存池实现

← linux内核多线程 内存池实现 →

Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式