2017-06-16 61 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我解釋過它是如何在原則上完成的,但是實現它取決於你。 –