C++11 中推出了三种智能指针,unique_ptr、shared_ptr 和 weak_ptr,同时也将 auto_ptr 置为废弃 (deprecated)。

但是在实际的使用过程中,很多人都会有这样的问题:

  1. 不知道三种智能指针的具体使用场景
  2. 无脑只使用 shared_ptr
  3. 认为应该禁用 raw pointer(裸指针,即 Widget * 这种形式),全部使用智能指针

本文将从这几方面讲解智能指针:

  1. 智能指针的应用场景分析
  2. 智能指针的性能分析: 为什么 shared_ptr 性能比 unique_ptr 差
  3. 指针作为函数参数时应该传,传值、传引用,还是裸指针?
阅读全文 »

最近在写 C++ 时,有这样一个代码需求:在 lambda 中,将一个捕获参数 move 给另外一个变量。
看似一个很简单常规的操作,然而这个 move 动作却没有生效。

具体代码如下:

std::vector<int> vec = {1,2,3};

auto func = [=](){
    auto vec2 = std::move(vec);
    std::cout << vec.size() << std::endl; // 输出:3
    std::cout << vec2.size() << std::endl; // 输出:3
};

代码可在 wandbox 运行。

我们期望的是,将对变量 vec 调用 std::move 后,数据将会移动至变量 vec2, 此时 vec 里面应该没有数据了。但是通过打印 vec.size() 发现 vec 中的数据并没有按预期移走。

这也就意味着,构造 vec2 时并没有按预期调用移动构造函数,而是调用了拷贝构造函数。

为什么会造成这个问题呢, 我们需要结合 std::movelambda 的原理看下。(最终的解决方案可以直接看 这里

阅读全文 »

随着 Golang 的兴起,协程尤其是有栈协程 (stackful coroutine) 越来越受到程序员的关注。协程几乎成了程序员的一套必备技能。

云风实现了一套 C 语言的协程库,整体背景可以参考其 博客

这个协程库非常轻量级,一共也才 200 多行代码,使用上更贴近于 lua 的写法(众所周知,云风是知名的 lua 粉)。整体基于 ucontext 和共享栈模型实现了有栈协程,代码质量毋庸置疑,本文将详细剖析该协程库的实现原理。

同时,我也提供了 coroutine 注释版,辅助大家理解 coroutine 的代码。

阅读全文 »

微信云支付 Android 智能 POS 使用 WebSocket 实现了用户订单的实时推送。即,顾客在扫描了门店的付款码,客户端会随即进行语音播报和打印等动作。

客户端利用 WebSocket 与后端维持长连接,当后端收到该门店订单时,即将成功态的订单通过对应的连接中。

然而,商户网络环境的多样性会导致 WebSocket 链路出现各种异常,从而引发漏单问题。

我们根据实际的场景,对此订单推送系统在稳定性上进行了大量优化,尽可能地提升了服务的可用性及自我恢复的能力。

阅读全文 »

在进行 Linux 网络编程开发的时候,免不了会涉及到 IO 模型的讨论。《Unix 网络编程》一书中提到的几种 IO 模型,我们在开发过程中,讨论最多的应该就是三种: 阻塞 IO非阻塞 IO 以及 异步 IO

本文试图理清楚几种 IO 模型的根本性区别,同时分析了为什么在 Linux 网络编程中最好要用非阻塞式 IO。

阅读全文 »

在客户端开发中,往往会有一些功能对时间要求比较严格,客户端需要获取到当前最准确的时间。但由于客户端环境多种多样,我们无法保证直接在客户端设备上获取到的时间是最准确的时间。
对于某些问题设备来说,设备时间与比当前实际的时间差了几个小时,甚至几天的情况都存在。倘若某功能依赖于当前时间,而客户端所提供的时间不准,就往往会给客户造成一些困扰。

那么,客户端如何能够获取到当前最准确的时间呢?

阅读全文 »