如何在指定的时间内执行任意函数并获得其返回值?

时间:2013-03-19 02:01:41

标签: c++ boost

我最初尝试this answer,但是在将'bind'的值分配给'int'(我的函数的返回类型,在这种情况下)时遇到了编译错误。我对增强有点不熟悉,但试图改进。有关如何在VC10上进行以下编译和正常工作的任何建议吗?

template <class T, class F>
void ExecuteWithReturn(const F &_bind, long sleep, T & ret)
{
    ret = _bind();
}

template <class T, class F>
bool TryExecuteFor(const F &_bind, long sleep, T & ret) {
    boost::thread thrd(ExecuteWithReturn<T, F>, _bind, boost::ref(ret));
    return thrd.timed_join(boost::posix_time::milliseconds(sleep));
}

结果是编译错误:

  

错误C2198:'void(__ cdecl *)(const boost :: _ bi :: bind_t   &amp;,long,T&amp;)':使用1&gt;调用的参数太少[1>   R =长,1> F = long(__ cdecl *)(const wchar_t *,const   wchar_t *,wchar_t **),1&gt;
  L = boost :: _ bi :: list3,boost :: _ bi :: value,boost :: _ bi :: value&gt;,1&gt; T = int 1> ]

并且该函数的用法应该是:

int ret;
if(!TryExecuteFor(boost::bind(g_pMyFunc, someParam, anotherParam), 10000, ret))
{
   ...
}

编辑:感谢Fraser指出了ExecuteWithReturn的明显问题;结合另一个修复程序使代码工作。运行后,我意识到一个非常可能的问题,如果线程是孤立的,传入的变量(包括返回值)可能会在函数返回之前超出范围。我对绑定仿函数的参数做不了多少,但为了减轻潜在的问题,我将返回值更改为shared_ptr。目前的工作实施如下:

template <class F>
void ExecuteWithReturn(const F &_bind, boost::shared_ptr<decltype(_bind())> _ret)
{
    *_ret = _bind();
}

template <class F>
bool TryExecuteFor(const F &_bind, long _timeout, boost::shared_ptr<decltype(_bind())> _ret) {
    boost::thread thrd(ExecuteWithReturn<F>, boost::ref(_bind), _ret);
    return thrd.timed_join(boost::posix_time::milliseconds(_timeout));
}

很容易TODO对于不返回值的函数会重载,但在基本测试之后它会按预期工作。

1 个答案:

答案 0 :(得分:4)

你在ExecuteWithReturn

中只有一个额外的参数

该功能可能应该更改为

void ExecuteWithReturn(const F &_bind, T & ret)

或者您需要传递sleep参数,并调用ExecuteWithReturn

boost::thread thrd(ExecuteWithReturn<T, F>, _bind, sleep, boost::ref(ret));