C++11/C++14支持std::future和std::async的异步调用,这本来是一件特别令人兴奋的事情,但是偏偏在C4droid平台(GCC 5.3 -std=c++14)上future模板无法使用,仔细研究了一下,future模板只是被forward declaration一下,在<future>头文件178、179行有这么一行宏定义组合
#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) \ && (ATOMIC_INT_LOCK_FREE > 1)1
但是到了C4droid上,ATOMIC_INT_LOCK_FREE = 1,这样future的实现(在这行的下面)就被宏注释掉了。所以future模板无法使用。
为了解决这个问题,尝试了一下几种方法:
Try 1
于是追踪ATOMIC_INT_LOCK_FREE这个定义,来到atomic_lockfree_defines.h中,发现定义:
#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
Try 2
把这个宏定义条件注释掉,直接越过定义,然而发现编译错误,exception_handle一类的东西,百度了一下,在头文件加了这么一行
#include <bits/exception_ptr.h>然后直接编译错误... 第40行,看了一下原因...直接血崩,居然还是ATOMIC_INT_LOCK_FREE在作怪。
于是直接define ATOMIC_INT_LOCK_FREE 2
然而还是各种编译错误...
Try 3
从编译参数角度考虑,在stackoverflow上找到了一个类似的问题,上面说-march=armv6即可。于是我就在编译参数加了-march=armv6 (之前的修改恢复原样)。这次倒是没有提示编译错误,然而连接错误... 爆出各种链接器错误,真是醉人... 我估计是我的设备是armv7所以没办法连接...
Try 4
最后的尝试:换了一个编译器CppDroid,顺便吐槽一下:这东西安装完成之后200多MB,而且还要联网下载,下载失败了不能编译也不能运行....
试了半天.. 最后还是一样的不好使... ATOMIC_INT_LOCK_FREE还是1。
搞了半天,还是无法实现异步调用,然而最近需要这个功能所以只好自己去实现。
初步代码如下:
#define FUNCTION_STD(FuncName,args...) void FuncName(int* _buildin_trg,##args) #define FUNCTION_START { #define FUNCTION_END *_buildin_trg=1;} #define NEWTHREAD(ThreadName,ThreadFunc,args...) _buildin_threadpack _buildin_threadpack_pack_##ThreadName(new thread(ThreadFunc,_buildin_threadpack_pack_##ThreadName.getpint(),##args)) #define ISOVER(ThreadName) (_buildin_threadpack_pack_##ThreadName.getint()==1) class _buildin_threadpack { private: thread* s; int status; public: _buildin_threadpack(thread* ins) { status=0; s=ins; } int getint() { return status; } int* getpint() { return &status; } ~_buildin_threadpack() { if(s!=nullptr) { s->join(); } delete s; } };本来想使用shared_ptr这样的智能指针的,但是感觉不是特别好用,所以写了一个比较粗糙的类来包装thread.
示例代码如下:
FUNCTION_STD(func) FUNCTION_START cout<<"In func"<<endl; FUNCTION_END int main() { NEWTHREAD(td,func); cout<<ISOVER(td)<<endl; this_thread::sleep_for(chrono::seconds(2)); cout<<ISOVER(td)<<endl; return 0; }
但是这个结构还没有考虑到FUNCTION异常退出等情况导致不能设置结束标记为1。对比future这个结构也没有wait_for和wait以及get调用。这些方法还是需要慢慢实现的。