項目在Ubuntu10 64位
boost 1.55,boost采用的是項目內包含相對目錄的形式部署
項目采用了 -Wall -Wextra -Werror -Wconversion 最高的告警選項
單獨測試是可以的
由於項目中包含的內容很多,頭文件超多,因此只能選取1個簡單的分支進行測試,可以再現問題,通過各種猜測和測試,最終定位到:
有GCC push_option對boost/thread進行處理後,stl容器使用完全異常[如 map<int,string>空內容時begin()!=end(),插入記錄崩潰或死循環,2個機器上運行有細微差別,死循環時gdb attach可以看到map操作無法結束];而不用push_option時一切正常
gcc -E 查看代碼的預處理結果看到內容太多,沒有再細致分析
既然gcc的這個選項和boost的thread有沖突,查看gcc的push_option說明,可見這個針對的時gcc 4.4,而ubuntu默認的gcc是version 4.4.3 (Ubuntu 4.4.3-4ubuntu5.1) ,猜測是否這個實現有些問題
既然此路不同,我們是否可以把第三方庫當成系統庫用,最簡單的方法時拷貝到/usr/include這類目錄,但這個方法不實用
查gcc的手冊,還真有這個選項-isystem https://gcc.gnu.org/onlinedocs/gcc-4.4.7/gcc/Preprocessor-Options.html#Preprocessor-Options
-isystem ${ProjDirPath}/../../others
最終項目配置成這個選項進行編譯即可
單獨新建工程如下,反而是正常的
g++ -L/opt/work/lib/static -L/opt/work/lib/ -o "zdemo" ./src/demo.o -lboost_system -lrt -lpthread -lboost_thread
#include <iostream>
#include <vector>
#include <map>
#pragma GCC push_options
#pragma GCC diagnostic ignored "-Wconversion"
#include <boost/thread.hpp>
#pragma GCC pop_options
#include <boost/make_shared.hpp>
#include <boost/bind.hpp>
using namespace std;
class Demo {
public:
Demo(const string & json){
this->rules[GET].push_back("hello");
this->rules[GET].push_back(json);
}
enum HttpMethod { ANY, GET, POST, PUT, DEL, OTHERS };
typedef vector<string> tRuleContainer;
map<HttpMethod, tRuleContainer> rules;
};
void demoThread(){
Demo u("world");
cout << u.rules.size() << endl;
}
int main() {
boost::shared_ptr<boost::thread> thrMon;
thrMon = boost::make_shared<boost::thread>(boost::bind(&demoThread));
Demo u("world");
cout << u.rules.size() << endl;
thrMon->join();
return 0;
}
這個當然是和 GCC 版本有關啦
考慮一些新特性的支持,選較新版本的 GCC
試試在bjam後加 -a選項, 去掉最後install 和 -without-python的選項.