使用cgo实现高性能WebSocket服务

Go 语言的便捷,协程的高效,GC以及自身的安全性,使得它成为后端业务开发的利器. 之前看过来自 Mail.Ru 工程师分享 Go的百万连接数的WebSocket服务优化 ,*中文翻译版.描述通过使用优化 Go 协程和零拷贝Http Header 实现了对内存的高效利用. 但其中自定义的 epoll 结构中依旧用了锁,个人觉得还是有优化的空间. 可以用高效的 uWebSockets 库配合,使得接入层用高效的 C++ 语言,而后端业务处理则用 Go 语言.这样的好处就是 C++ 可以最高效精准的把控接入层的逻辑处理和内存的使用,而后端的业务开发则是以高效安全为主,使用 Go 正好合适. 这里使用的 uWebSockets 为 0.14.8 tag 的版本,配合 libuv作为事件驱动,zlib 作为压缩算法库,openssl 作为加密库,四个编译为 .a类型的静态库,方便一同编译到程序中,避免运行时动态库缺失的问题. … “使用cgo实现高性能WebSocket服务”

Read More

QT下无法执行C++编译

安装QT完成后,无法执行c++项目的构建: Could not determine which “make” command to run. Check the “make” step in the build configuration. Error while building/deploying project xxx (kit: Desktop Qt 5.10.1 GCC 64bit) When executing step “qmake” 一般以为是qmake或make问题,但其实是C++的编译工具没指定:

Read More

C++ 17的variant和auto的尝试

std::variant 强类型语言的一个特定就是当要使用一个变量时,必须要确定该变量的类型,并且一旦声明后,就不可更改. 但是 C++17 中收录来自 Boost 库的 variant,它通过一系列复杂的模板,绕过了这个规则.当然,如果使用这个类型,性能会存在些微的损失: variant v, w; v = 12; int i = get(v); w = get(v); w = get(v); // same effect as the previous line w = v; // … “C++ 17的variant和auto的尝试”

Read More

hiredis异步调用的接口封装

hiredis 是来自 redis 官方的 C 语言驱动(官方没有推出C++版的驱动,其他的都不是官方的,请认准一家),支持所有 redis 功能的调用,并且包含同步与异步模式,效率极高。 下载最新的稳定版0.13.3,使用make生成静态库和动态库,选择是否install安装到系统环境中。我通常直接将库放到项目中,指定include路径,这样可以减少项目中开发的环境不一致问题。 再要求高并发的项目中,应该尽量避免使用同步的方法,虽然同步的编程难度相比于异步而言要低很多。hiredis 中同时提供了同步和异步的调用接口,其代码质量十分优秀。 使用异步的接口需要导入头文件hiredis.h和async.h,最后还要导入异步事件的驱动头文件,hiredis 提供了对 ae,libev,libevent,libuv,qt 还有 macosx 异步库的支持,相应头文件在 adapters 文件夹中,这里用 uv 库. 头文件如下: #include “hiredis/hiredis.h” #include “hiredis/async.h” #include “hiredis/adapters/libuv.h” typedef struct redisConfig { char addr[256];//the full … “hiredis异步调用的接口封装”

Read More

QT-模态对话框与非模态对话框笔记

模态与非模态的定义: 模态对话框(Modal dialog box):只可在当前程序的当前对话框执行操作,不允许对当前程序的其他对话框执行操作。 非模态对话框(Modeless dialog box):打开当前程序的一个窗口后,仍能在当前程序的其他窗口执行操作。 在QT里创建对话框需包含头文件< QDialog>,创建非模态对话框可以用三种方法,常用的是在调用时new;第二种是提前声明其为类中成员函数;第三种是全局声明,这种很少用。 非模态对话框在调用时new,需注意空间的释放问题。 使用setAttribute属性事件接收Qt::WA_DeleteOnClose 事件,让QWidget在触发关闭事件时,自动delete。 setAttribute说明: void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on = true) 其返回值空,第二参为true时,接受第一参设置函数属性,false则清除事件属性。第二参不填则默认ture. WA_DeleteOnClose说明: Qt::WA_DeleteOnClose属于enum Qt::WidgetAttribute中的55。 其作用是接受关闭事件时,delete QWidget. //代码示例 QMenuBar *mBar = menuBar();//创建菜单栏 QMenu *pDlg = mBar->addMenu(“Menu”);//创建菜单 … “QT-模态对话框与非模态对话框笔记”

Read More

C++14之初窥

之前C++标准委员会憋了好多年的大招,终于憋出了C++11.而且C++11也不负众望,带来了很多的新特性的同时也修补了许多C++原先的一些不足,比如右值引用的问题.而这次C++标准委员会却很快就通过了最新的C++14标准。 因此这次改动应该就只是修补了原先C++11上的一些不足,正如C++之父Bjarne Stroustrup所言: C++14 is simply the completion of the work that became C++11. When you finish a huge project, there are things you know need to be done, but you can’t add them if … “C++14之初窥”

Read More

C++11之enum

C++11加强了enum类型,推出了强类型的enum,语法格式为 enum class E : T { __VA_ARGS__, }; 在此之前C++的enum继承自C,只能说是弱鸡,比如: 1. 同作用域下,两个不同枚举空间中的值如果取相同的名称将会冲突. 2. 存在隐式转换,通常情况下两种不同枚举是没有比较的意义的,但由于默认C风格底层为int型enum,则可以相互比较. 3. C中的枚举如果数值越界,也不会报错,转换之后存在数据丢失的风险. 而使用C++11中强化了的enum,其改变有: 1. 强化了作用域,使用时必须指定enum的名称,因此不用担心枚举中值名称重复. enum class cycle{red,black,white}; enum class car{red,black,white}; 不可隐式转换.即不同的枚举空间的值不可相互比较. 可以指定底层类型,因此既可以节约空间,又可以指定符号. enum class cycle:char{red=0,black=3,white}; enum class car:short{red=-2,black,white};

Read More

C++的多线程

C++11 新标准中引入了四个头文件来支持多线程编程,他们分别是<atomic> ,<thread>,<mutex>,<condition_variable>和<future>。 <atomic>:该头文主要声明了两个类, std::atomic 和 std::atomic_flag,另外还声明了一套 C 风格的原子类型和与 C 兼容的原子操作的函数。 <thread>:该头文件主要声明了 std::thread 类,另外 std::this_thread 命名空间也在该头文件中。 <mutex>:该头文件主要声明了与互斥量(mutex)相关的类,包括 std::mutex 系列类,std::lock_guard, std::unique_lock, 以及其他的类型和函数。 <condition_variable>:该头文件主要声明了与条件变量相关的类,包括 std::condition_variable 和 std::condition_variable_any。 <future>:该头文件主要声明了 std::promise, std::package_task 两个 Provider 类,以及 std::future 和 std::shared_future 两个 … “C++的多线程”

Read More

C++11之Lambda与bind

Lambda语法和stl::bind 都是语法糖,但不得不说它们的作用很出色: 1. 更方便的定义匿名函数 2. 更简洁的代码逻辑 3. 更安全的私有函数 这称之为closure,即闭包. Lambda 表达式语法有如下五种形式: [capture](parameters) mutable throw() ->return_type {body} [capture](parameters) mutable ->return_type {body} [capture](parameters) ->return_type {body} [capture](parameters) {body} [capture] {body} capture []用于标识一个lambda的开始,其中可以存在零个或多个捕获参数,用逗号分隔.并且只允许以下两种标识符表示: & 引用值 = 拷贝值 对于参数的形式可以有: 1. … “C++11之Lambda与bind”

Read More

C++11之for

C++11中新加了基于范围的for循环,可以对集合/数组/初始化列逐个访问,这种用法在其他高级语言里早有实现,现在C++终于支持了. for的新特性是的代码更加的简洁: //原来的方法 for (std::vector<int>::const_iterator itr = myvec.cbegin(); itr != myvec.cend(); ++itr) //C++11中auto和for新特性结合 for (auto& x : myvec) 简直屌爆了有木有. 对于自定义的集合类型支持foreach,只需实现begin和end函数即可,因为内置的STL模板会自动适配: template <typename Container> auto begin (Container& cont) -> decltype (cont.begin()); template <typename Container> auto begin … “C++11之for”

Read More