2014-11-20 87 views
0

後開始的線程所以我試圖建立一個服務器,接受套接字上的連接,然後創建一個線程圍繞執行一個函數,使用新接受的連接的文件描述符。我遇到的問題是,當我啓動線程時,服務器返回接受另一個連接(如果有的話)但它不會阻塞?它似乎是從循環返回,我不知道它爲什麼這樣做。該代碼正在運行的是:程序終止accept()

listen(sockfd,10); 
int i = 0; 
for(;;) 
{ 
    std::cout << "Before accept" << endl; 
    clilen = sizeof(cli_addr); 
    newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); 
    std::cout << "After accept" << endl; 

    if (newsockfd < 0) 
    { 
     std::cout << newsockfd << ": Error on accept" << endl; 
     continue; 
    } 
    else 
     std::cout << newsockfd << ": Connection accepted!" << endl; 

    boost::thread(boost::bind(&Class::FunctionToRun, this, newsockfd)).start_thread(); 
    std::cout << ++i << endl; 
} 

輸出到腳趾控制檯:

Socket opened! fd = 3 
Before accept 
After accept 
4: Connection accepted! 
1 
Before accept 
[program terminates] 

但如果接受塊,同時等待套接字上一個新的連接,那麼怎麼來的程序之前「之後,終止接受「被打印?

+0

進程是否崩潰? – 2014-11-20 20:48:09

+0

你不希望它返回並再次接受()嗎?當你說「終止」時,誰終止了它?你殺了它,還是它自己死了? – Barry 2014-11-20 20:48:23

+0

@BrianWalker我不這麼認爲。運行在它自己的線程中的進程應該沒問題。如果線程中發生的事情沒有按預期發生,它可以終止程序的其餘部分嗎? – Stapps 2014-11-20 20:50:50

回答

1

的問題是,你在瞬間摧毀你的線程沒有加入它:

boost::thread(boost::bind(&Class::FunctionToRun, this, newsockfd)).start_thread(); 
    // already dead here 
    std::cout << ++i << endl; 
} 

如果你想你的線程流連,你需要將它們存儲在什麼地方:

std::vector<std::unique_ptr<boost::thread>> threads; 
for (;;) { 
    // ... 
    threads.emplace_back(new boost::thread(boost::bind(...))); 
    // thread is still alive here 
    std::cout << ++i << endl; 
} 

如果沒有C++ 11,那麼你可以使它成爲vector<boost::shared_ptr<boost::thread>>來完成同樣的事情。

+0

我不想讓我的線程流連在一起。我希望他們儘快開始。 – Stapps 2014-11-20 21:41:14

+1

@Stapps只要你創建它們,它們就會立即開始 - 你只需要*對象*就可以四處走動,否則它會被破壞......並且你不希望它在你完成之前被破壞。 – Barry 2014-11-20 22:00:25

+0

你的代碼似乎可以工作,但無論如何,在將線程添加到列表(我不得不使用push_back,因爲它是pre-C++ 11)之後,我仍然遇到了accept()問題。因此,在接受另一個連接之前,接受仍然終止程序。 – Stapps 2014-11-20 23:07:19