分类目录归档:C++

sort 导致进程崩溃

转载自沙子泥巴刘的博客

前言

最近被一个在sort自定义排序导致的崩溃问题, 弄得焦头烂额. 后在网上看了这篇文章, 才解决问题, 转载一次.

正文

近期我们开发的一个工具在调用c++ sort函数对数组进行排序时居然会导致进程崩溃,此问题细节我觉得对于类似我这种不常用stl的同学可能不容易觉察,这里简单总结下。

出错代码

因为代码太复杂不好展示,我这里就用下面这个简单的示例来描述。

#include <algorithm>

bool comp(int d1, int d2)
{
    return d1 >= d2;
}

const int N = 50;

int main()
{
    int d[N];
    for(int i = 0; i < N; ++i)
    {
        d[i] = 20;
    }

    std::sort(d, d + N, comp);
    return 0;
}

不知你是否直觉上也会觉得这段代码没什么问题,但是这段代码运行后会core dump。查看core文件可以看到内存里的栈被写坏了,这说明sort调用导致了内存越界访问,在这么少的代码行下,不难判定应该是comp函数实现可能不符合c++标准库的某种规则(C++ STL是基于concept的设计和实现)。
继续阅读

流量优化

服务器带宽流量

带宽跟流量是个怎么也不能忽略的问题, 如果无法做好流量优化, 服务端写得再好, 客户端依然会卡.

客户端卡顿分析

如果服务器与客户端之间, 平均流量为100k, 客户端的网络情况为200k, 那么平时推送客户端不会卡顿, 可是实际上客户端会生成某些数据,这些数据的生成需要大量的历史数据才能完成, 假设需要2M的历史数据. 那么实际上我们将花费10秒左右的时间才能完成此数据的推送. 这个时候整个客户端会表现为不走数据, 用户就会觉得, 这是什么鬼!!!
继续阅读

hiredis 异步

hiredis

hiredis是redis官方库, 提供了同步与异步的接口. 对于高性能的服务器, 异步的接口给我们很大的发挥空间.

同步还是异步

使用同步还是异步并没有绝对的定论, 我们可以根据一些性能表现确定使用同步或是异步. redis性能非常好, 以至于在插入或是读取单条数据的时候几乎是感觉不到差异的. 可是一旦同时插入大量数据, 同步延迟非常严重, 读取平均长度30的kv, 大约是10万/秒, 如果我们有千万级别的数据, 整个卡顿会上分钟, 而且带宽会被打满, 所以一般大数据的读取, 我们会采用异步的方法.
继续阅读

libevent zmq消息无法响应

前言

服务器使用libevent做事件循环, 然后使用zmq做线程间通讯, libevent监听zmq的消息, 一旦zmq有消息过来, 就会回调到固定的函数。使用zmq需要注意的是, 一旦zmq消息回调, 必须读空整个队列的消息. 否则下次就不会回调。

问题症状

我们使用libevent监听了多个zmq, 同时监听了别的事件(退出事件等). 其中有一个zmq消息非常繁忙, 每秒会产生上万到十万不等的数据. 这种时候会发现libevent再也无法响应其他消息。
继续阅读

ZMQ 高级请求-应答封包解包

我理解的ZMQ

ZMQ不是消息队列, 是一套构建消息队列的组件集合, 它告诉你每个组件有什么特性, 每个组件可以干什么, 至于怎么构建消息队列, 全凭自己决定. 我们可以搭建出同步的, 异步的, 可靠的, 不可靠的, 分布式的, 非分布式的等等. 正是这种灵活的方式, ZMQ才能满足各式各样的需求(借别人一句话:ZMQ就像是一盒积木,只要你有足够的想象力,就可以用它组装出任何造型的网络架构).
继续阅读

浅析事件驱动与消息驱动

事件

简而言之就是发生了一件事情, 文件读完了, socket打开了, socket关闭了, 指的是一件发生了的事情.

消息

message, 我们可以认为就是简单的几个单词, 比如:张三告诉我文件读完了, 我获得了一个消息, 这个消息是张三告诉我的, 关于文件读完的消息.
继续阅读

时间戳转换日期

前言

时间戳转日期是我们最常用的需求, 一般情况我们会采用系统提供的localtime或localtime_r来转换, 可是localtime是线程不安全的, 而且两个都是通过系统调用来实现的, 如果在大量调用的时候, 会导致整个系统性能低下, 这也就是为什么我们要通过数学的方法转换时间戳.
继续阅读