【问题标题】:Starting thread from Poco::HTTPServer从 Poco::HTTPServer 启动线程
【发布时间】:2016-02-09 20:16:02
【问题描述】:

我遇到了从 Poco::HTTPServer 启动线程的奇怪行为

这是我得到的:

class Worker : public Poco::Runnable {
public:
    Worker(std::string request): _request(request) {};
    void run();
    std::string GetResult();
private:
    std::string _request;
};

void Worker::run() {
    // do something with _request;
}

class RequestHandler : public HTTPRequestHandler {
public:
  virtual void handleRequest(HTTPServerRequest &req, HTTPServerResponse &resp) {

    std::string request(static_cast<stringstream const&>(stringstream() << req.stream().rdbuf()).str());

    Poco::Thread thread;
    Worker worker(request);

    std::string response = "";

    thread.start(worker);

    // parsing content of the request to detect if request is async or sync

    if(async) {
    // make dummy response 
        response = "your request queued";
    } else { // if sync
        thread.join();
        response = worker.GetResult();
    }
    ostream& out = resp.send();
    out << response;
    out.flush();
  }

private:
};

现在,如果请求是同步类型的,一切正常,RequestHandler 等待线程的加入,然后以工作者的结果响应,一切正常。但是如果请求是异步类型的,我不需要等待线程加入,我只需要在工作线程继续处理请求时发送一​​个虚拟响应。几个异步请求后的问题是段错误。像这样:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff2e4c700 (LWP 13986)]
0x0000000000000000 in ?? ()
(gdb) bt
#0  0x0000000000000000 in ?? ()
#1  0x00007ffff7a3f76e in Poco::ThreadImpl::runnableEntry (pThread=0x7ffff464e930) at /home/uzurik/libs/poco-PostgreSQL/Foundation/src/Thread_POSIX.cpp:436
#2  0x00007ffff66c26aa in start_thread (arg=0x7ffff2e4c700) at pthread_create.c:333
#3  0x00007ffff69dfeed in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

我做错了什么?

【问题讨论】:

    标签: c++ multithreading thread-safety poco-libraries


    【解决方案1】:

    你得到segfault的原因是当async为真时线程没有加入。 Worker 将在线程之前被销毁,run() 是否在那个时候完成是一个偶然的问题(请记住,它在单独的执行线程中运行)。访问已销毁对象的状态会导致未定义的行为。

    如果你交换ThreadWorker 的声明,Thread 将首先被销毁,但究竟会发生什么(最终肯定是坏事)取决于Worker::run() 是否已经开始执行。

    因此,join(或其他形式的同步)是保证有序执行和清理的唯一方法。在任何其他情况下,您都有可能发现自己处于已销毁的 Worker 对象的成员函数中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多