消息队列总结

一、为什么需要无锁队列?
二、无锁队列是什么?
三、无锁队列是如何实现的?

    inline yqueue_t() {
        begin_chunk = (chunk_t *)malloc(sizeof(chunk_t));
        alloc_assert(begin_chunk);     
        begin_pos = 0;
        back_chunk = NULL;
        back_pos = 0;
        end_chunk = begin_chunk;
        end_pos = 0;
    }

    inline ~yqueue_t() {
        while (true) {
            if (begin_chunk == end_chunk) {
                free(begin_chunk);
                break;
            }
            chunk_t *o = begin_chunk;
            begin_chunk = begin_chunk->next;
            free(o);
        }
        chunk_t *sc = spare_chunk.xchg(NULL);   
        free(sc);                               
    }```

## 1.初始化完成后队列数据状态:

![在这里插入图片描述](https://img-blog.csdnimg.cn/1f7997ef1c2a44fdaee9e6281f95f7b6.png)
begin_pos总是指向队列中数据的第1个元素(初始情况除外,初始情况队列中没有元素)
back_pos 总是指向队列中数据的最后一个元素的下一个位置
end_pos   总是指向队列中数据的最后一个元素的下一个位置的下一个位置(其中没有存数据)

```c
    inline void push() {
        back_chunk = end_chunk;
        back_pos = end_pos;

        if (++ end_pos != N) return;
        chunk_t *sc = spare_chunk.xchg(NULL);
        if (sc) {                            
            end_chunk->next = sc;
            sc->prev = end_chunk;
        } else {
            end_chunk->next = (chunk_t *)malloc(sizeof(chunk_t));
            alloc_assert(end_chunk->next);  // ???
            end_chunk->next->prev = end_chunk;  
        }
        end_chunk = end_chunk->next;
        end_pos = 0;
    }

2.经过初始化然后第一次 push 操作后的队列数据状态:

在这里插入图片描述

三、其他相关知识

    在函数中无法直接定义函数,但可以通过类或Lambda表达式达到类似效果。
    但在类中或函数中可以直接定义类。
#include <iostream>
using namespace std;

void foo() {
    class innerfunc {
    public:
        void operator () () {
            cout<<"inner function object"<<endl;
        }
    };
    innerfunc foo;
    foo();
    
    auto lambdafunc = [=]()->void {
        cout<<"inner lambda expression"<<endl;
    };
    lambdafunc();
}

int main() {
    foo();
    return 0;
}

锁(本质上是一个资源)
1.互斥锁 2.自旋锁 —— 互斥类型的锁
3.读写锁 —— 应用于多读少写的场景(数据库中的行锁)
4.信号量(多应用于多层级的缓存) 5.条件变量 —— 同步类型的锁

无锁
6.原子变量、内存屏障

IPC(进程间通信)
1.pipe(无名管道)
2.FIFO(有名管道)
3.信号量
4.信号
5.消息队列
6.共享内存
7.socket

事务ACID特性
原子性(Atomicity):事务中包括的所有操作要么都做,要么都不做。
一致性(Consistency):数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。
隔离性(Isolation):
持续性(Durability)

事务之间具有三种执行方式
1.串行执行——单处理机系统(事务串行执行方式)
2.并发执行——单处理机系统(事务交叉并发执行方式)
3.并行执行——多处理机系统(事务同时并发方式—>多个事务真正的并行运]

互斥锁与自旋锁区别

互斥锁:
pthread_mutex_lock(&mutex);
pthread_mutex_unlock(&mutex);
当互斥锁被占用后,其他线程申请锁时会进入阻塞状态(让出CPU),加入阻塞队列,等待锁资源被释放。

自旋锁
pthread_spin_lock(&spinlock);
pthread_spin_unlock(&spinlock);
当自旋锁被占用后,其他线程会循环等待(不会让出CPU)一段时间,然后调用sched_yield()直接进入就绪对列,等待下一次CPU资源被释放

主要区别就是执行时,先是从就绪队列中获取任务,故自旋锁执行优先级高于互斥锁。
自旋锁属于非公平锁,属于主动型锁
互斥锁属于公平锁,属于被动型锁,等待系统公平(FIFO)分配资源。

文章参考与<零声教育>的C/C++linux服务期高级架构系统教程学习:

服务器高级架构体系:https://ke.qq.com/course/417774?flowToken=1010783
音视频开发体系:https://ke.qq.com/course/3202131?flowToken=1040744
dpdk系统学习:https://ke.qq.com/course/5066203?flowToken=1043154
内核系统学习:https://ke.qq.com/course/4032547?flowToken=1042705
golang云原生体系:https://ke.qq.com/course/422970?flowToken=1043281

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值