任意函数调用的boost ::拉姆达::绑定? [英] Arbitrary function call with boost::lambda::bind?

查看:144
本文介绍了任意函数调用的boost ::拉姆达::绑定?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要使用一个外部库,提供大量的做了很多的东西联网功能免费。这个库,不幸的是,不是很故障保护,并且它发生卡住在其中的一些功能永远(或至少一个非常长的时间)。这不是我的选择,所以我想中断呼叫如果时间太长。

I have to use an extern library providing lots of free functions that do a lot of networking stuff. This library, unfortunately, is not very failsafe, and it happens to get stuck in some of these functions forever (or at least a very long time). This is not an option for me, so I want to interrupt the call if it is taking too long.

纵观在<一个href=\"http://stackoverflow.com/questions/879896/c-how-to-implement-a-timeout-for-an-arbitrary-function-call\">C++: ?如何实现任意函数调用超时和的boost ::拉姆达图书馆,我想出了这一点:

Taking a look at C++: How to implement a timeout for an arbitrary function call? and the boost::lambda library, I came up with this:

#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>

int foo(int a, int b) {
    boost::this_thread::sleep(boost::posix_time::seconds(2));
    return a+b;
}

int main() {
    int ret;
    boost::thread thrd(boost::lambda::var(ret) = boost::lambda::bind<int>(&foo, 1, 2));
    if(thrd.timed_join(boost::posix_time::seconds(1))) {
        std::cout << ret << std::endl;
    }
    else {
        std::cerr << "Function timed out." << std::endl;
    }
    return 0;
}

编译和工程就像一个魅力。但问题是,我有很多的功能,使用不同的参数和返回值,并写入上述每一个案例似乎是繁琐和多余的工作给我。所以我想它包装在一个函数:

Compiles and works like a charm. The problem however is, that I have lots of functions with different parameters and return values, and writing the above for every case seems like tedious and redundant work to me. So I want to wrap it in a function:

template <class t> t timeout(bindparam<t> &bind /* read below */, long sleep) {
    t ret;
    boost::thread thrd(boost::lambda::var(ret) = bind);
    if(thrd.timed_join(boost::posix_time::milliseconds(sleep))) {
        return ret;
    }
    else throw std::runtime_error("timeout");
}

的想法是,我可以运行的重要功能。

The idea is that I can run the critical function with

try {
    int ret = timeout<int>(boost::lambda::bind<int>(&foo, 1, 2), 500);
    std::cout << ret << std::endl;
}
catch(std::runtime_error &e) {
    std::cerr << e.what() << std::endl;
}

但我不知道如何做到这一点,还是它甚至有可能。我可以通过任意的boost ::拉姆达::绑定 s到我的功能不知何故?

but I have no idea how to do this, or whether it is even possible. Can I pass arbitrary boost::lambda::binds to my function somehow?

更新:

的建议,我与尝试过的boost :: packaged_task

template <class T> T timeout(boost::packaged_task<T> &f, long sleep) {
    T ret;
    boost::thread thrd(boost::lambda::var(ret) = f);
    if(thrd.timed_join(boost::posix_time::milliseconds(sleep))) {
        return ret;
    }
    else {
        thrd.interrupt();
        throw std::runtime_error("timeout");
    }
}

但是当我尝试使用它作为超时&LT; INT&GT;(升压:: packaged_task&LT; INT&GT;(提高::绑定(安培;富,1,2)),500); 我得到一个奇怪的编译器错误:

But when I try to use it as timeout<int>(boost::packaged_task<int>(boost::bind(&foo, 1, 2)), 500); I get a strange compiler error:

main.cpp: In function ‘int main(int, char**)’:
main.cpp:35: error: no matching function for call to ‘timeout(boost::packaged_task<int>, int)’

不是超时(升压:: packaged_task&LT; INT&gt;中INT) pretty多正是我的超时函数签名,除了将被隐式转换的 INT 部分?我在做什么错了?

Isn't timeout(boost::packaged_task<int>, int) pretty much exactly my function signature of timeout, except for the int part that will be converted implicitly? What am I doing wrong?

更新2:

我终于得到它的工作,但我不知道我在做什么是这样做的一个很好的方式,因为我发现它令人难以置信很难找到的boost ::任何文件或实例packaged_task 键,基本上所有我的工作是的来源$ C库$ C 。这是我工作的功能:

I finally got it to work, but I have no idea whether what I am doing is a good way of doing it, because I found it incredibly hard to find any documentation or examples on boost::packaged_task and basically all I worked with is the source code of the library. Here is my working function:

template <class T> T timeout(boost::packaged_task<T> &f, long sleep) {
    boost::thread thrd(boost::lambda::bind(&boost::packaged_task<T>::operator(), &f));
    if(thrd.timed_join(boost::posix_time::milliseconds(sleep))) {
        boost::unique_future<T> ret = f.get_future();
        return ret.get();
    }
    thrd.interrupt();
    throw std::runtime_error("timeout");
}

我不与它完全满意,主要是因为它不与临时工作,这意味着你必须去这种方式来使用它:

I am not completely happy with it, mainly because it does not work with temporaries, meaning you have to go this way to use it:

try {
    boost::packaged_task<int> f(boost::lambda::bind(&foo, 1, 2));
    int sum = timeout<int>(f, 500);
    std::cout << sum << std::endl;
}
catch(std::runtime_error &e) {
    std::cerr << e.what() << std::endl;
}

我仍然非常高兴,如果有人更善于利用​​这种结构可以在此发表评论。

I would still be very happy if someone more adept with these structures could comment on this.

推荐答案

将这项工作?

template <class T, class F>
T timeout(const F &bind, long sleep) {
    T ret;
    boost::thread thrd(boost::lambda::var(ret) = bind);
    if(thrd.timed_join(boost::posix_time::milliseconds(sleep))) {
        return ret;
    }
    else throw std::runtime_error("timeout");
}

这篇关于任意函数调用的boost ::拉姆达::绑定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆