C++11/C++14支持std::future和std::async的异步调用,这本来是一件特别令人兴奋的事情,但是偏偏在C4droid平台(GCC 5.3 -std=c++14)上future模板无法使用,仔细研究了一下,future模板只是被forward declaration一下,在<future>头文件178、179行有这么一行宏定义组合
1
2#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) && (ATOMIC_INT_LOCK_FREE > 1)
在PC上的CodeBlocks中,_GLIBCXX_HAS_GTHREADS = 1,_GLIBCXX_USE_C99_STDINT_TR1 = 1,ATOMIC_INT_LOCK_FREE = 2。
但是到了C4droid上,ATOMIC_INT_LOCK_FREE = 1,这样future的实现(在这行的下面)就被宏注释掉了。所以future模板无法使用。
为了解决这个问题,尝试了一下几种方法:
Try 1
于是追踪ATOMIC_INT_LOCK_FREE这个定义,来到atomic_lockfree_defines.h中,发现定义:
1
2#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
然而__GCC_ATOMIC_INT_LOCK_FREE这个变量并不存在于任何头文件中... 这个宏定义应该是编译器自己定义并掌握的。因此这种方法无法解决问题。
Try 2
把这个宏定义条件注释掉,直接越过定义,然而发现编译错误,exception_handle一类的东西,百度了一下,在头文件加了这么一行
1#include <bits/exception_ptr.h>
于是直接define ATOMIC_INT_LOCK_FREE 2
然而还是各种编译错误...
Try 3
从编译参数角度考虑,在stackoverflow上找到了一个类似的问题,上面说-march=armv6即可。于是我就在编译参数加了-march=armv6 (之前的修改恢复原样)。这次倒是没有提示编译错误,然而连接错误... 爆出各种链接器错误,真是醉人... 我估计是我的设备是armv7所以没办法连接...
Try 4
最后的尝试:换了一个编译器CppDroid,顺便吐槽一下:这东西安装完成之后200多MB,而且还要联网下载,下载失败了不能编译也不能运行....
试了半天.. 最后还是一样的不好使... ATOMIC_INT_LOCK_FREE还是1。
搞了半天,还是无法实现异步调用,然而最近需要这个功能所以只好自己去实现。
初步代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33#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; } };
示例代码如下:
1
2
3
4
5
6
7
8
9
10
11
12FUNCTION_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; }
第一次isover返回0,第二次返回1
但是这个结构还没有考虑到FUNCTION异常退出等情况导致不能设置结束标记为1。对比future这个结构也没有wait_for和wait以及get调用。这些方法还是需要慢慢实现的。
最后
以上就是哭泣大雁最近收集整理的关于手动实现类似std::async与std::future的异步调用的全部内容,更多相关手动实现类似std::async与std::future内容请搜索靠谱客的其他文章。
发表评论 取消回复