概述
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
在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中,发现定义:
#define ATOMIC_INT_LOCK_FREE
__GCC_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;
}
第一次isover返回0,第二次返回1
但是这个结构还没有考虑到FUNCTION异常退出等情况导致不能设置结束标记为1。对比future这个结构也没有wait_for和wait以及get调用。这些方法还是需要慢慢实现的。
最后
以上就是哭泣大雁为你收集整理的手动实现类似std::async与std::future的异步调用的全部内容,希望文章能够帮你解决手动实现类似std::async与std::future的异步调用所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复