【问题标题】:Flask, boost::python and threads烧瓶、boost::python 和线程
【发布时间】:2015-04-08 02:38:11
【问题描述】:

我有一个通过 boost::python: 公开的 C++ 类

class RunnerState {
public:
    RunnerState(std::string& input) : m_output(3, 0) {  }
    std::vector<int>& get_output() { return m_output; }
    void run() {
        std::unique_lock<std::mutex> running(m);
        t = new std::thread([this] (std::unique_lock<std::mutex> running) {
            sleep(10);
        }, std::move(running));
    }
    bool is_running() {
        if(m.try_lock()) {
            m.unlock();
            return false;
        }
        return true;
    }
private:
    std::thread *t;
    std::mutex m;
};

BOOST_PYTHON_MODULE(librunner)
{
    class_<std::vector<int>>("int_vector").def(vector_indexing_suite<std::vector<int>>());
    class_<RunnerState, boost::noncopyable>("RunnerState", init<std::string>())
        .def("get_output", &RunnerState::get_output, return_value_policy<copy_non_const_reference>())
        .def("run", &RunnerState::run)
        .def("is_running", &RunnerState::run);
}

然后由 Flask 网络服务使用:

from flask import Flask, request
import librunner
app = Flask(__name__)
current_run = None

@app.route('/run', methods=['POST'])
def run():
    data = request.get_data()
    current_run = librunner.Run(data)
    output = current_run.get_output()
    # do something with output...
    current_run.run()
    return "Success!", 200, {'Content-Type': 'text/plain'}

@app.route('/running')
def running():
    result = False
    if current_run != None:
        result = current_run.is_running()
    return str(result), 200, {'Content-Type': 'text/plain'}

问题是 POST/run 的请求在 C++ 中创建的线程退出之前不会返回。为什么?

我猜这与 Boost::Python 返回值策略和 Boost::Python 保持返回值在指定时间内保持活动有关,但我无法具体找出问题所在。

【问题讨论】:

    标签: python c++ multithreading flask boost-python


    【解决方案1】:

    这里的问题是 current_run 全局函数不被函数访问,而是它们每个都得到一个名为 current_run 的局部变量。这可以通过将 python 更改为:

    from flask import Flask, request
    import librunner
    app = Flask(__name__)
    current_run = None
    
    @app.route('/run', methods=['POST'])
    def run():
        data = request.get_data()
        global current_run
        current_run = librunner.Run(data)
        output = current_run.get_output()
        # do something with output...
        current_run.run()
        return "Success!", 200, {'Content-Type': 'text/plain'}
    
    @app.route('/running')
    def running():
        result = False
        global current_run
        if current_run != None:
            result = current_run.is_running()
        return str(result), 200, {'Content-Type': 'text/plain'}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-02
      • 1970-01-01
      • 2017-10-18
      • 1970-01-01
      • 2018-05-24
      • 1970-01-01
      • 2015-09-29
      • 1970-01-01
      相关资源
      最近更新 更多