2020年3月26日
| 字数
1978
The future is the value, the promise is the function that sets the value – essentially the return value (future) of an asynchronous function (promise). Setting the value of a future is also called resolving, fulfilling, or binding it. —— from Wikipedia 1 Preface Seastar (f-p-c) 属于Reactive编程的一个子集。 Seastar的性能源自 sharded,cooperative,non-blocking的微任务调度设计, 而 f-p-c 是将 task 送入调度程序的一种更友好的方式。 Seastar 引入了 future/promise, 把面向 callback 编程变成了面向future/promise编程, 将以前的回调代码包装在 lambda_task 中,然后交给future调度。 future 是一个 value ; promise 是一个函数,本质是返回 value 的异步函数; promise 写入 value 的过程又称为解决、履行或绑定它。 具体来说,当……
阅读全文
2020年3月26日
| 字数
782
1 MS Office 如果作为开发人员,工作场合需要经常使用 MS Office,那么在尝试比较 MS Office 文件时会遇到一些问题。 也许你在问自己:这有什么问题? 这是:MS Office 将生成 Git 无法比较的二进制文件。 之前在 Windows 平台下,我们使用的文本转换工具,将二进制文件转化为text,然后再diff。 catdoc(用于 Word) xls2csv(用于 Excel) catppt(用于幻灯片) 2 寻找新的方案 目前主要使用MacOS系统,想看看有没有更好的方案? 通过搜索,发现一个更通用的文本转换工具:textract。它不仅支持Office全家桶,还支……
阅读全文
2020年3月19日
| 字数
2220
1 问题描述 有 T 层楼,n个鸡蛋,鸡蛋是相同的,临界楼层是指从某个楼层之上抛下来,都会碎,但从这个楼层之下抛下来,都不会碎。没有碎的鸡蛋可以重复使用。试假设能找到这个临界楼层需要抛投的最少次数。 T层,n个鸡蛋, 总是先要任选一层k, 扔下一个鸡蛋;扔下之后有两个结果: 没碎: 则需要在高层求解 F(T-k, n) 碎了: 则在k层以下求解 F(k-1, n-1) 假设我们在第 k 层扔下第一个鸡蛋,最坏的情况下,我们需要扔多少次: cost(k, T, n) = max{F(T-k, n), F(k-1, n-1)} + 1 我们把每一层,遍历一下最坏情况下所有方案的,最少扔鸡蛋的次数: F(T, n) = min{cost(1, T, n), cost(2, T, n), …, cost(k, T, n), …, cost(T, T, n)} 2 实现 简……
阅读全文
2020年3月15日
| 字数
1746
1 问题描述 使用std::thread 创建线程, 代码逻辑如果主动throw 某些异常, 但是用户又没有捕获。这时候程序会产生coredump, 但是分析coredump, 会发现调用栈是缺失的,根本无法定位具体问题。 为了方便理解,下面给一个例子: 1 2 3 4 5 6 7 8 9 10 11 12 13 // g++ -std=c++0x -g test.cpp -lpthread -o test #include <stdexcept> #include <thread> void foo() { throw std::runtime_error("foo"); } int main() { std::thread t(foo); t.join(); } 直接运行就会产生coredump, 通过gdb 分析: $ gdb test core.1243 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Program received signal SIGABRT, Aborted. [Switching to Thread 0x7ffff7fd0700 (LWP 10278)] 0x000000318f036285 in raise () from /lib64/libc.so.6 Missing separate debuginfos, use: debuginfo-install glibc-2.14.90-24.fc16.9.x86_64 libgcc-4.6.3-2.fc16.x86_64 libstdc++-4.6.3-2.fc16.x86_64 (gdb) bt #0 0x000000318f036285 in raise () from /lib64/libc.so.6 #1 0x000000318f037b9b in abort () from /lib64/libc.so.6 #2 0x00000031964bbc5d in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib64/libstdc++.so.6 #3 0x00000031964b9e16 in……
阅读全文
2020年2月7日
| 字数
920
1 嵌套lambda表达式 写一个lambda表达式A,其入参是一个lambda表达式B: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #include <cstdio> #include <iostream> namespace example01 { template<typename Func> void run_task(Func &&func) { int arg = 100; printf("1. arg >> %d\n", arg); /** * 定义一个别名,进行引用捕获 * (注意:引用捕获时,请考虑被捕获对象的生命周期) */ func([&i = arg]() mutable { ++i; printf("3. i == %d\n", i); throw std::logic_error("逻辑错误"); }); printf("6. arg << %d\n", arg); } inline void run() { //写一个lambda表达式A,其入参是一个lambda表达式B example01::run_task([](auto get_ex) { printf("2. start check\n"); try { get_ex(); } catch (std::exception &ex) { std::cout << "4.……
阅读全文
2020年1月16日
| 字数
2093
1 Preface 最近对框架进行了改造,支持yaml格式的配置文件, 使用到了 yaml-cpp 这个第三方库, yum官方提供的是 0.5.1 版本(依赖boost),看到最新版 0.6.3 已经去除了boost的依赖, 于时想自己做一个包。 制作 rpm 包通用的方式是: 直接使用rpm-build, 编写project.spec,这样就需要了解spec的语法规则。 今天不经意在网上搜到,可以用CMake来制作RPM包(因为我们的 C++ 项目也是采用 CMake 进行编译的)。 CMake打包的基本原理是:CMake内部有一个cpack工具,支持调用不同的打包工具(比如 rpmbuild) 下面我们就基于C……
阅读全文
2019年12月18日
| 字数
892
1 Preface 我们在 Linux 服务端编程的时候,select/epoll 可以监控多个fd, 并且可以指定超时时间。 那么我们在Go 里面也有select 关键字,那么怎么实现超时机制呢? 在 select 中加入一个 timer channel case rc2 := <-time.After(d): After等待持续时间过去,然后在返回的通道上发送当前时间。 它等效于NewTimer(d)。 在计时器触发之前,底层的计时器不会由垃圾收集器恢复。 如果需要提高效率,请改用NewTimer,如果不再需要计时器,请调用Timer.Stop。 完整代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 // 采用 select 实现超时……
阅读全文
2019年12月17日
| 字数
1750
1 Preface 反射是程序在运行时检查变量和值, 并获取到它们的类型的能力。 很多主流语言都提供了反射语法特性,比如Java, python等; C++语言本身不支持反射, 但是第三方库实现了反射特性, 比如 google 的 protobuf。 如果支持反射,解决某些场景的问题,可以变得简单。 比如通过struct/class, 生成对应的建表语句,根据生成 insert 语句(批量将CSV导入数据库)等。 在之前的文章中,我们了解了如何在 Java/C++ 中使用反射: Java-反射机制 protobuf-反射 2 Go 反射 Go语言中使用空的接口,表示任一类型(可以理解为Any……
阅读全文
2019年11月27日
| 字数
2673
1 Preface 最近 C++ 后台微服务组件,考虑使用etcd集群,替换 zookeeper 集群。 这篇先讨论实现服务的注册与发现,节点的上线和下线通知。后面讨论服务的负载均衡。 etcd基于raft协议,通过复制日志文件的方式来保证数据的强一致性。 在etcd之前,常用的是基于 paxos 协议的 zookeeper。 2 etcd 介绍 etcd是一个golang编写的分布式、高可用的一致性键值存储系统,用于提供可靠的分布式键值(key-value)存储、配置共享和服务发现等功能。 etcd可以用于存储关键数据和实现分布式调度,在现代化的集群运行中能够起到关键性的……
阅读全文