tornado.gen.coroutine 使用初识

准备使用 tornado 4.0 开发业务服务.
目前有一个场景, 即客户端发送一个 auth post请求过来, 但服务器属于边缘节点,
需要把 auth 转发到真正的后台服务器.
此时有两种方式发送:
1. 边缘节点在接收到 post 请求, 然后调用 tornado.httpclient.HTTPClient()
同步获得结果 response
2. 异步方式操作, 不影响其他用户的请求(即不阻塞进程)
在阅读 tornado demo 的 authdemo.py 源码时 有一个 @gen.coroutine 使用
于是查阅相关资料, 并做了代码验证.

Continue reading

C++11 学习笔记(11) std::move 右值引用 初识

std::move

参考链接:
c++ 右值引用 原文
详解C++右值引用
std::move
std::remove_reference
value_categary

例子:
int i = 101;
auto j = std::move(i);

Visual Studio 2013 的源码

其含义是 获取其参数的右值(rvalue)引用, 并转变为另一个 xvalue.

Continue reading

value_category (cppreference.com 文档翻译) (校正 by 囧多)

原文链接: http://en.cppreference.com/w/cpp/language/value_category

Value categories:

Each C++ expression (an operator with its arguments, a literal, a variable name, etc) is characterized by two
independent properties: a type and a value category. Each expression has some non-reference type, and each
expression belongs to exactly one of the three primary value categories.

每个C++表达式(带有参数的运算符, 一个字面值, 一个变量名, 等等) 由两个属性来定性:
一个 type 表达式类型 和 一个 value category 值分类. 每个表达式都有一个或者
多个非引用类型, 每一个表达式都仅属于3大值分类中的一类.

Continue reading

判断 ipv4 与 ipv6 地址 C++实现原理(boost源码为例)

在使用 boost asio 时, 对 accept类初始化时的过程感到兴趣,
因此调试过程中, 观察了其 bind 和 listen之前对服务器地址的处理.

调试观察的 boost 源码版本为 1.55.0

boost 源码的判断的思路:
1. 优先判断是否为 ipv6 地址
2. 其次判断是否为 ipv4 地址
3. 判断地址的关键的系统调用 inet_pton
boost 源码的 boost::asio::detail::socket_ops::inet_pton
其实最后调用的是系统的 inet_pton, 封装的名字够深的, 哈哈

inet_pton 的描述:

截取的 boost 源码:

Continue reading

TCP/IP UDP/IP 传输数据的应用层包大小如何定

本文的写作起因:
本人负责项目中手机底层通信模块开发, 和做游戏的前端同事
沟通网络手游时的网络状况. 听到同事描述各种的网络环境
(咨询的是游戏更新时, 下载更新包的环境):
1. wifi连接情况, 正常的情况, 连接网络质量良好的 wifi
2. wifi连接情况, 两个wifi都可以自动连接的情况下, 手机一会连接 wifi-a, 一会 wifi-b
3. 3G网络连接(壕啊, 一款网络手游上百兆都有可能, 下载速度都可能比 使用运营商家用宽带服务的都快)
4. 2G网络连接(这个情况都有玩家更新 –b )

由以上场景, 当时联想到熟悉的词: MTU(Maximum Transmission Unit, 最大传输单元)
在各种网络环境下, 也包括PC端, 都有一个 MTU 的缩写词, 有时候家用网络优化,
百度搜索都有答案告诉你 修改系统 MTU 的值.

同时在自己的项目里, 对自己有个问题, 一次发多少大小以内的 tcp/udp 数据包合适?

通过查询资料, 做个记录:

Continue reading

C++11 学习笔记(10) std::atomic i; ++i 前缀自增运算的原子性分析

目前项目中使用到了多线程, 我选择 C++11 std::thread 库实现,
模仿开源的流媒体服务器 crtmpserver 里的 protocol类,
每生成一个实例类, 都会有全局的唯一id.
在整个函数声明周期里, 定义:
static u_int32_t idGlobalGenerator; // 初始化0
即当一个类生成时, 该实例类的私有成员 u_int32_t id_;
在构造函数里初始化 id_ = idGlobalGenerator++;
由于我的开发场景是多线程, 因此 idGlobalGenerator
被声明为:

执行 ++idGlobalGenerator; 操作, 根据文档和语义它是原子性的. 而在这里产生的疑惑是:

u_int32_t id = ++idGlobalGenerator;

该执行是否是原子性, 保证多线程环境下, 赋值的 id都是唯一的值.
于是我在 stackoverflow上直接提了问题(当时没有亲自验证): 链接

Continue reading

C++11 学习笔记(9) 线程与信号 改进2 atomic

本文基于 C++11 学习笔记(7) 线程与信号 添加上了 atomic 支持做的改进:

改进的参考资源:
C++11 atomic 与 mutex 性能比较
stackoverflow 讨论C++11 atomic 与 mutex 速度
介绍 atomic 并发的博客
C++11 atomic memory model
C++11 修复了双重检查锁定问题

引用 wilburding作者的 C++11 atomic memory model文章(http://wilburding.github.io/blog/2013/04/07/c-plus-plus-11-atomic-and-memory-model/) :

C++11 atomic 与 mutex 性能比较 的博客 也提到 使用 std::mutex
直接调用lock unlock 的性能开销比 lock_guard 或者 atomic大的多.

因此针对系列笔记 (7)的代码作了优化:

Continue reading

C++11 学习笔记(8) 使用bind改进 rtmpd iohandler 与 protocol 的绑定关系的思路

rtmpd ( 即 crtmpserver )的 是C++版本的流媒体服务器,
其实现方式与 Java 版本的 red5类似. 源码中有大量的指针互相
注册, 以便每个类都能找到对应的功能类, 做通知功能或者传输数据.
而指针的声明周期又需要作者自己清楚地了解(没有用到 shared_ptr).
也许在 C++11推出后, 可以方便地使用 std::bind 与 std::function
来重新定义类之间的关系, 通过互相的注册函数(包括通知函数).

在 rtmpd 的 docs 文档中有一个 architecture.txt 描述了 rtmpd 的代码结构:

Continue reading