2016-02-09 21 views
0

我遇到一個奇怪的行爲開始從波科:: HttpServer的一個線程從波科:: 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: 
}; 

,如果請求是同步的鍵入all ok,RequestHandler等待線程的連接,然後用worker的結果響應,一切正常。但是如果請求是異步類型的,我不需要等待線程連接,我只需要在工作線程繼續處理請求時發送一​​個虛擬響應。在幾次異步請求之後,問題是segfault。像這樣:

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 

我做錯了什麼?

回答

0

你得到段錯誤的原因是因爲當async爲真時線程沒有連接。 Worker將在線程之前銷燬,並且run()當時是否已經完成(請記住,它在單獨的執行線程中運行)是一個偶然的問題。訪問被銷燬的對象的狀態會導致未定義的行爲。

如果你交換的ThreadWorker的聲明,Thread將首先摧毀,但到底發生了什麼(最終肯定是壞事)取決於Worker::run()是否已經開始執行與否。

因此,聯接(或某種其他形式的同步)是保證有序執行和清理的唯一方法。在其他情況下,您冒着發現自己處於被銷燬對象的成員函數中的風險。