怎样让 C++ 中 throw exception 产生的 coredump 带上栈

1. 问题

一个 C++ 程序,如果 throw 了 exception ,但是又没有 catch,那么一般会产生 coredump, 问题是,在 gcc 4.x 版本产生的 coredump 文件中,没有 throw 时候的堆栈信息,导致不知道是哪里 throw 的,没法查问题。

原因是 gcc 4.x 的 /libstdc++-v3/src/c++11/thread.cc:92 里面有个 catch(…),所以 stack unwind 了,就没了 throw 时候的 stack 。

1
2
3
4
5
6
7
void * execute_native_thread_routine(){
    try {
     ...   
    }catch(...){
        std::terminate();
    }
}

https://abcdabcd987.com/libstdc++-bug/

一个解决办法是可以升级 GCC 7 ,或者可以用更简单的办法:

pdqsort-qsort

可以对抗输入数据模式的排序算法。 quick sort 在输入数据接近有序的情况下,效率不高。 Pattern-defeating quicksort (pdqsort) is a novel sorting algorithm that combines the fast average case of randomized quicksort with the fast worst case of heapsort, while achieving linear time on inputs with certain patterns.

用 abstract unix socket 实现进程单实例运行

一,问题背景

很多时候,我们需要确保进程只有一个实例运行

有几种方法:

http://stackoverflow.com/questions/2964391/preventing-multiple-process-instances-on-linux

http://stackoverflow.com/questions/5339200/how-to-create-a-single-instance-application-in-c-or-c

https://github.com/qtproject/qt-solutions/tree/master/qtsingleapplication/src

比较常规的做法,是对一个文件加文件锁 flock,比如对 pid 文件 flock( LOCK_EX|LOCK_NB )

但是这种方法有些弊端:

  1. 如果文件被 mv 或者 rm,是会被绕过的。
  2. 如果磁盘故障比如磁盘满,目录没有写权限,会失败。

二,abstract namespace unix socket

http://linux.die.net/man/7/unix

unix socket 有3种:

  1. 基于文件的
  2. socketpair 创建的,匿名的
  3. abstract namespace 的,Linux特有

Linux 下, AF_UNIX socket 支持一种特殊的 abstract namespace unix socket 。

相比 普通的基于文件系统的 unix socket,abstract namespace unix socket :

  1. 没有磁盘文件
  2. 进程挂了以后自动删除,无残留文件
  3. 无需担心与 文件系统上的文件冲突,不需要关心文件系统上的绝对路径是否存在的问题

Python 自动翻译成 C++ ,彻底保证离线在线特征一致

一,问题背景

随着深度学习的广泛应用,在搜索引擎/推荐系统/机器视觉等业务系统中,越来越多的深度学习模型部署到线上服务。

机器学习模型在离线训练时,一般要将输入的数据做特征工程预处理,再输入模型在 TensorFlow PyTorch 等框架上做训练。

1.常见的特征工程逻辑

常见的特征工程逻辑有:

  1. 分箱/分桶 离散化
  2. log/exp 对数/幂等 math numpy 常见数学运算
  3. 特征缩放/归一化/截断
  4. 交叉特征生成
  5. 分词匹配程度计算
  6. 字符串分隔匹配判断tong
  7. 缺省值填充等
  8. 数据平滑
  9. onehot 编码,hash 编码等

这些特征工程代码,当然一般使用深度学习最主要的语言 python 实现。

二,业务痛点

离线训练完成,模型上线部署后,同样要用 C++ 重新实现 这些 python 的特征工程逻辑代码。

我们发现,“用 C++ 重新实现” 这个步骤,给实际业务带来了大量的问题:

  1. 繁琐,费时费力,极容易出现 python 和 C++ 代码不一致
  2. 不一致会直接影响模型在线上的效果,导致大盘业务指标不如预期,产生各种 bad case
  3. 不一致难以发现,无法测试,无法监控,经常要靠用户投诉反馈,甚至大盘数据异常才能发现

用 DAT 重实现 CppJieba 中文分词算法,降低 99% 内存消耗

一,问题背景

中文分词应用比较广泛的开源算法,是 jieba 结巴分词,结巴分词较高性能的实现是 C++ 版本的 CppJieba : https://github.com/yanyiwu/cppjieba

在实际使用 CppJieba 的过程中,我们发现 CppJieba 的内存占用比较高。

比如对一个 76W 词 大小 11MB 的词典 ,加载 2份 (比如为了支持平滑改动用户词典)就需要耗费 505MB内存。

这对一些多进程的后台服务,浪费大量内存,难以接受,因此这里希望削减内存耗费。

经过初步调查,确定改进方法,然后动手改造,最终把 505MB 缩减到了 4.7MB ,实现了 99% 内存降低

此处也有 issue 讨论 https://github.com/yanyiwu/cppjieba/issues/3

代码在 https://github.com/byronhe/cppjieba