2017-06-16 55 views
0

我知道这不是用来解答我的问题的最佳方式。在我的服务器中,一些问题基本上归结为此 - 一旦满足conditionA,你如何从while循环中断开?如果满足条件B,是否可以销毁特定的线程?如何从活动线程中断开while循环

不幸的是,主线程永远被recvfrom()函数阻塞,除非我可以从循环中断开。

while (1) 
{ 
    recBytes = recvfrom(sock, packetBuff, 8, 0, (struct sockaddr *) &client, &SockLength); 

    std::thread TX([&] 
    { 
    //process packet task 

    if(conditionA == 1) 
     break from while loop 

    if(conditionB == 1) 
     destroy any active threads spawned by TX 

    . 
    . 
    . 
    much more tasks 

    }); 

    TX.detach(); 
} 

. 
. 
. 
continue rest of code 

在此先感谢!

+1

你有没有考虑过使用一些asio库?想到boost.asio,但也有其他库可用。尽管如上所述,从另一个线程关闭套接字是简单而有效的,可以从recv_from退出,并检查错误情况,因为我希望你已经做到了。 break语句将退出循环。 –

+0

我可以在YT上建议这个讲座:“时间史:异步C++ - 史蒂文辛普森”吗?在使用现代C++技术设计客户端/服务器应用程序之前,这非常值得。无论您的应用需要多大尺寸。 –

+0

@MichaëlRoy你介意在代码中展示这看起来像什么吗? – djent

回答

1

从阻塞I/O调用中断的标准方法是用select()/ poll()/ etc替换它,它在2个套接字上等待:数据套接字和非阻塞通知管道。如果select()报告可以读取或写入数据套接字,则可以非阻塞的方式做到这一点。如果报告数据在通知管道上可用,则会从循环中断开。任何线程都可以将单个字节写入非阻塞通知管道,以使另一个线程中的select()返回。

至于销毁其他线程,如果没有这些线程的合作,就无法做到这一点。基本上,你需要一种方式来通知他们他们需要退出。如果这些线程不做阻塞调用,那么定期检查一个简单的原子标志就可以做到。否则,你需要一种方式来阻止呼叫。如果是I/O呼叫,则引入另一个通知管道。如果它在条件变量上阻塞,使用std :: condition_variable :: notify_all()。

+0

检查boost.asio代码示例:http://www.boost.org/doc/libs/1_64_0/doc/html/boost_asio/example/cpp11/echo/async_udp_echo_server.cpp –

+0

@Tulon你介意让我看看编码这将看起来像请?我不能使用第三方库 – djent

+0

@djent我解释过它是如何在原则上完成的,但是实现它取决于你。 –