2014-11-20 116 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