存档

‘c++’ 分类的存档

nginx + fastcgi + c/c++

2016年7月18日 1 条评论

使用php写后端程序的例子很多,用c/c++的比较少。

本文采用nginx,spawn,fastcgi++来构建一个基于cgi的web程序。
由于fastcgi++依赖于boost库,我们先来装boost库

Linux下编译boost

1.编译前的准备工作

2.下载安装包并解压

编译安装

测试boost库是否可以使用,boost编译完成后运行程序报错,

最开始以为是bzip2没装上,折腾了许久也没搞定,最后我发现boost的官方文档写着gcc4.4.7,而我本地的编译器是4.4.6,之后我把gcc升级到4.8重新编译通过。

redhat6.3升级gcc4.8.0编译安装方法:

1.下载源码并解压

2.下载编译所需的依赖项

3.建立编译输出目录
mkdir gcc-build-4.8.0

4.进入此目录,执行以下命令,生成makefile文件

5.执行以下命令进行编译,编译时间比较长

6.安装
sudo make install

安装完成后查看版本

重新执行boost的编译,编写一个例子测试是否成功

编译运行

spawn-fcgi安装

fastcgi安装

启动fastcgi程序

如果启动报错,可以加参数-n来看具体原因。

我的报错如下,因为升级了gcc4.8,没有升级libstdc++.so.6导致。

/usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.15' not found错误的解决

没有3.4.15

连接到libstdc++.so.6新的库

再次启动fastcgi程序

程序会在前台运行
检查程序是否正常运行

配置nginx,增加

重新加载ngnx的配置

打开浏览器,访问http://192.168.18.11/utf8-helloworld.fcgi,你会看到。
English: Hello World
Russian: Привет мир
Greek: Γεια σας κόσμο
Chinese: 世界您好
Japanese: 今日は世界
Runic English?: ᚺᛖᛚᛟ ᚹᛟᛉᛚᛞ

参考
http://www.cnblogs.com/skynet/p/4173450.html
http://www.cnblogs.com/wanghetao/p/3934350.html
http://www.nongnu.org/fastcgipp/doc/2.1/index.html

分类: c++, nginx 标签:

enumeration value not handled in switch

2016年5月17日 没有评论

这是一个 warnning 错误,没有处理switch中的枚举值。

在switch中添加default 和 break; 可以解决这个问题。

分类: c++ 标签:

mac下c++单元测试覆盖率工具gcov

2016年5月1日 没有评论

gcov 是 GNU 的代码覆盖率检查工具。它利用编译时的 -fprofile-arcs -ftest-coverage 和链接时的 -lgcov 选项参数生成 .gcno 文件进而通过这些文件统计覆盖率。不过高版本的 mac 使用 clang 编译器,不支持 -lgcov 选项生成 .gcno 文件。为了解决这个问题,我们可以使用-coverage参数来生成 .gcno 文件。例如:

我的g++ --version信息如下
Apple LLVM version 7.3.0 (clang-703.0.29)
Target: x86_64-apple-darwin15.4.0
Thread model: posix
使用-lgcov会报错
ld: library not found for -lgcov

可以使用-coverage选项替换-lgcov

在C/C++中产生代码覆盖率的步骤包括如下几步:
一、设置编译参数
如下来设置Makefile中的编译参数以使之支持覆盖率产生:
ifeq ($(coverage), yes)
CXXFLAGS += -coverage
endif
这样,可以使用 make coverage=yes 来引入这些编译选项而不会影响到正常的编译,比如:
#make coverage=yes
这时候会产生.gcno文件。

二、运行测试程序
#./exe
运行测试程序,会针对所有cpp源代码产生相应的.gcda文件。

三、获取覆盖率数据
获取覆盖率数据的方法很多种,这里介绍两种,分别产生txt和html数据:
1、使用gcov获取文本形式的覆盖率数据
使用gcc自带的覆盖率结果产生工具gcov能产生文本格式(.gcov)的覆盖率结果。
#gcov xxx.cpp
2、使用lcov获取html形式的覆盖率数据
使用IBM的lcov来产生html结果数据,具体如下:
#lcov -c -d ./ -o app.info
#genhtml app.info -o cc_result

四、展示数据
将步骤三中产生的覆盖率数据文件放到Apached的htdocs目录下,就能通过浏览器来查看覆盖率结果了。

五、基本术语
1、行覆盖率(line coverage)
即源代码有效行数与被执行的代码行的比率。
2、分支覆盖率(branch coverage)
即有判定语句的地方都会出现2个分支,整个程序经过的分支与所有分支的比率是分支覆盖率。
3、增量覆盖率(incremental coverage)
即被执行的新增和修改的代码行数与新增和修改的代码总行数的比率。

gcov实际例子,通过运行gtest中的sample1.cc单元测试。

makefile文件的写法

编译程序

编译完成后直接执行gcov命令,会报未执行,需要先执行可执行文件

执行可执行文件

使用gcov查看sample1.cc文件的覆盖率

表示:sample1.cc一共有13行(可执行代码),全部被执行,测试覆盖率100%。
具体哪些代码被测还可以看sample1.cc.gcov文件:

-表示该行不可执行,数字1或其他表示该行被执行了多少次,#####表示代码没被执行。

分类: c++ 标签:

Tuxedo中string导致内存泄漏

2016年4月30日 没有评论

对象创建的时候会调用构造函数来初始化对象,对象销毁的时候会调用析构函数。

普通的自动变量(local非static)包含构造函数和析构函数。
当进入变量作用域的时候构造函数被调用,当离开变量作用域的时候析构函数被调用。

当在tuxedo的环境中调用 tpreturn() 或者 tpforward() 函数时,编译器进行了一个non-local的goto (using longjmp(3)),导致自动变量的析构函数没有被调用。

为了避免这个问题,我们应该在服务体中调用直接调用 tpreturn()tpforward() (而不是在服务体调用的函数中调用这两个函数)。

ps:

1.服务体中不能包含包含析构函数的变量,特别是string变量,这些带析构函数的自动变量需要放到函数调用体中,这样当离开函数的作用域的时候,会析构这些变量。如果在服务体中有string变量,那么随着服务循环会有内存泄漏。

2.自动变量需要被嵌套在服务体函数中的大括号{}包围,大括号需要在调用tpreturn()tpforward() 函数前结束。

可以改为:

附原资料
C++ constructors are called to initialize class objects when those objects are created, and
destructors are invoked when class objects are destroyed.

For automatic (that is, local, non-static) variables that contain constructors and destructors, the constructor is called when the variable comes into scope and the destructor is called when the variable goes out of scope.

However, when you call the tpreturn() or tpforward() function, the compiler performs a non-local goto
(using longjmp(3)) such that destructors for automatic variables are not called.

To avoid this problem, write the application so that you call tpreturn() or tpforward() from the service
routine directly (instead of from any functions that are called from the service routine).

In addition, one of the following should be true:

1 The service routine should not have any automatic variables with destructors (they should
be declared and used in a function called by the service routine).

2 Automatic variables should be declared and used in a nested scope (contained within curly
brackets {}) in such a way that the scope ends before calling the tpreturn() or
tpforward() function.

分类: c++ 标签:

[0;32m eclipse显示颜色

2016年4月7日 没有评论

用 eclipse cdt 运行 gtest 在 console 的输出结果有有 shell 终端的颜色代码输出
Running main() from gmock_main.cc
[==========] Running 4 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 4 tests from PrimeFactors
[ RUN ] PrimeFactors.1factor
[ OK ] PrimeFactors.1factor (0 ms)
[ RUN ] PrimeFactors.2factor
[ OK ] PrimeFactors.2factor (0 ms)
[ RUN ] PrimeFactors.3factor
[ OK ] PrimeFactors.3factor (0 ms)
[ RUN ] PrimeFactors.4factor
[ OK ] PrimeFactors.4factor (0 ms)
[----------] 4 tests from PrimeFactors (0 ms total)

[----------] Global test environment tear-down
[==========] 4 tests from 1 test case ran. (0 ms total)
[ PASSED ] 4 tests.

如何让 console 的输出和 shell 中的输出效果相同。

可以通过在 eclipse market 安装 ANSI escape 来解决。

分类: c++ 标签:

gtest和gmock入门实例

2016年1月10日 没有评论

对于 c++ 来说写单元测试和 mock 框架不是一件容易的事情。还好, Google 为我们搭建了一个出色的单元测试和 mock 框架。网上的例子很多都过多强调概念,本文用一个简单的例子让大家对于什么是 gtest 和 gmock 让大家有一个直观的了解,让大家很快上手,就像写 hello word 一样容易。

gtest&gmock 的 1.6 版本的使用 make 编译,新版的已经已经迁移到 github 上使用 cmake 编译,安装过程很多,这里不在重复,如果大家有需要再单独写。

1.下载安装 Google Test and Google Mock
2. 编译生成静态库gtest_main.a gmock_main.a (包含main库后不需要自己写main函数)

gmock用来对与为实现对象的接口模拟。

我们有一个Messgener.h接口,它的getMessage目前还没有实现,可以使用mock类提供的宏来模拟,这样就可以调试客户端程序,屏蔽Messgener.h的具体实现

Messenger.h 的 mock 类

调用Messenger.h的客户端程序

HelloWorld.h

HelloWorld.cpp

有了要测试的代码和依赖的接口的mock模拟类,下面是gtest的单元测试写法:

单元测试结果
gtest

分类: c++ 标签: ,

c++虚函数和纯虚函数的区别

2015年12月13日 没有评论

多态是C++的重要特性,通过基类指针来访问派生类的函数。

虚函数就是为了实现这功能而定义的函数,虚函数可以在定义时实现也可以不实现,定义了虚函数的类可以实例化。

纯虚函数更多的是表示接口的含义,纯虚函数定义时不能实现,需要在派生的子类中实现且必须实现,含有纯虚函数的类不能实例化。

虚析构函数与虚函要成对出现,以便在通过基类指针释放派生对象时,调用派生类的析构函数。

阅读全文...

分类: c++ 标签:

clang: warning: argument unused during compilation: '-pthread'

2015年12月9日 1 条评论

编译gtest时报了一个警告错误,查询发现有人说重装clang,可是我不会重装,不想折腾一直是使用自动升级来更新xcode。
c++ -isystem ../../googletest/include -isystem ../include -g -Wall -Wextra -pthread -lpthread gmock_test.o gmock_main.a -o gmock_test
clang: warning: argument unused during compilation: '-pthread'

后来发现so上有一篇纪实,也就是说clang时编译时使用这个参数,链接的时候时不使用这个参数的,所以可以忽略这个警告。
clang requires -pthread when compiling but not when linking.

This is annoying, but it is observed behavior:

$ clang -c x.cpp
$ clang -pthread -c x.cpp
$ clang -o x x.o
$ clang -pthread -o x x.o
clang: warning: argument unused during compilation: '-pthread'

$ clang --version
Apple LLVM version 7.0.0 (clang-700.1.76)
Target: x86_64-apple-darwin15.0.0
Thread model: posix

分类: c++ 标签: ,

mac环境下eclipse cdt开发环境配置

2015年11月28日 没有评论

本文将一步步介绍如何在osx下配置eclipse开发c++代码环境和使用实例

安装前准备

1.安装过java
2.安装过xcode

下载安装eclipse

访问eclipse网站下载mac版c++开发包,选择64bit,下载地址
eclipse_url
阅读全文...

分类: c++, iOS/Mac 标签:

动态更新运行中程序的配置信息

2014年10月18日 3 条评论

一个程序投产线上使用基本不会停下来,一旦业务需求改变或者增加需求,需要修改配置文件时,往往需要停机修改配置后重新启动服务。

这个过程进程少还可以接受,如果停一次机要很长时间而且需要授权更新,这个是难以接受的方法。

想了几个办法
1.放到内存,例如redis这种字典,这样可以动态修改redis的值来实现动态更新,问题是如何保证redis出问题不影响原程序呢?
重redis里读到map,如果需要的配置不在,到内存里去读,这样只能增加配置,想要删除配置好像不理想。

2.定时load配置文件,

3.通过信号load,

2.和3.不好协调多个进程服务一致性问题。

真伤脑筋啊。

有人知道好方法,告诉我一下。