簡體   English   中英

C ++對象和線程

[英]C++ objects and threads

我正在做一個簡單的服務器復制,其中可以有多個連接,每個連接都是一個線程。 這是我想要的示例(不起作用),有一個線程集合,其中每個線程實例化類連接的對象:

class connection{};

class server{
std::vector<std::thread> active_connections;
public:
    void listen() {active_connections.push_back(std::thread(connection));}
};

我一直在尋找解決方案,但是最好的發現是一些成員函數線程。 當我測試該解決方案時,它變得非常錯誤,例如:

class connection{};

class server{
std::vector<std::thread> active_connections;
public:
    void new_connection() { ... }
    void listen() { 
        active_connections.push_back(std::thread(&server::new_connection,this)); }
    };

消息是:錯誤:使用已刪除的函數'std :: thread :: thread(const std :: thread&)。 這是否意味着std :: thread類想要復制服務器類? 我不太了解C ++,所以請不要大驚小怪,我只是在問。

謝謝!

編輯:

這是發生這種情況的地方:

void server::do_listen()
{   
    int addr_size = sizeof(sockaddr_in);
    sockaddr_in client_sock;
    connection_info cn_info;

    while(true)
    {
        int csock;
        if((csock = accept(server_sock, (sockaddr*)&client_sock, (socklen_t*)&addr_size)) != -1)
        {
            printf("Incomming connection from %s.\n", inet_ntoa(client_sock.sin_addr));
            memset(&cn_info,0, sizeof(connection_info));
            cn_info.sock_addr = client_sock;
            cn_info.sock = csock;
            std::thread thr(&server::new_connection, *this, cn_info);
            thr.join();
        }

    }
}

到目前為止。 server::new_connection()仍然為空。

問題在這里:

std::thread thr(&server::new_connection, *this, cn_info);
                                         ^

您正在綁定服務器對象的副本 不可復制,因為它包含不可復制thread對象(的容器)。 而是綁定一個指針:

std::thread thr(&server::new_connection, this, cn_info);

有些人可能會發現λ更易讀; cn_info值捕獲this指針和cn_info

std::thread thr([=]{new_connection(cn_info);});

如評論員所述,您可以通過綁定參考包裝器來混淆解決方案:

std::thread thr(&server::new_connection, std::ref(*this), cn_info);

但我更喜歡在可能的情況下消除而不是增加復雜性。

這是否意味着std :: thread類想要復制服務器類?

不,這意味着在某處復制了std::thread ,但在NonCopyable中將其作為std::thread禁止使用 (請注意,構造函數列表中的thread(const thread&) = delete; )。

您應該消除執行thread副本的所有代碼。 您發布的那個不會執行此類復制。

在“幕后”制作副本的示例是線程變量向量中的push_back ,即:

std::thread myThread;
myVector.push_back(myThread);

在您的代碼中:

active_connections.push_back(std::thread(&server::new_connection,this)); 

當您推回一個臨時文件時,它不會被復制而是被移到向量中。

給您更多的設計問題:

您為一個連接創建一個線程。 如果有十個連接,則有十個線程。 但是,如果要處理10000個連接,該怎么辦? 我不確定您的操作系統喜歡那樣。

僅在我看來,一種更好的連接處理方法是:只有N個線程來處理網絡連接。 如果您的計算機具有例如六個核心,則可以僅花一個,兩個或更多線程來處理網絡事務。 因此,您為此擁有一定大小的線程池。

前攝器模式可能對您很有趣:

http://en.wikipedia.org/wiki/Proactor_pattern

如果您正在尋找一個可以處理此類問題的庫,則可以查看即將推出的名為Boost.Asynchronous的C ++ Boost庫:

https://github.com/henry-ch/asynchronous

該庫仍在開發中,但確實不錯。 我使用該庫制作了一些簡單的客戶端/服務器應用程序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM