2015-04-08 37 views
1

我有一个是通过升压::蟒露出的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); 
} 

这然后被的烧瓶中的web服务:

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使得返回的值在指定的时间内保持活动状态,但我无法明确地发现问题所在。

回答

1

这里的问题是current_run全局不被函数访问,而是他们每个都得到一个本地调用current_run。这是通过更改蟒蛇来解决的:

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'}