0

私は次のコードを持っています:

try
{
    HAS::TCPServerSocket servSock(echoServPort);    // Socket descriptor for server
    std::vector<HAS::TCPSocket*> sockets(MAXCONN);
    for (;;)
    {
        try
        {
            if (socketCount < MAXCONN)
            {
                HAS::TCPSocket* sock(servSock.accept());
                sockets.push_back(sock);
                std::thread handler(handleTCPClient, std::ref(sockets[socketCount++]));
                handler.detach();
            }
        }
        catch (...)
        {
            cerr << "Unable to create thread" << endl;
            exit(1);
        }
    }
}

限られた数の接続を追跡したいのですが、(MAXCONN=4)を使用して開いたソケットを追跡したいと思いstd::vectorます。どういうわけか、上記のコードを使用すると、sock変数はで受け入れられるように現在のソケットに適切に設定されservSock.accept()ます。ただし、sock変数を押し込もうとするとstd::vector、靴下オブジェクトが緩みます。

コピーおよび/または移動コンストラクターを適切に指定する必要があると感じていますが、両方を定義しました(そして、ブレークポイントを使用して、いつ呼び出されるかを確認しました)が、まったく呼び出されないようです。

4

2 に答える 2

4

と言うと、ベクトル要素への参照は無効になりますpush_back。あなたが持っているようにコードを使うことはできません。最初にベクトル全体にデータを入力してから、二度とタッチしないようにする必要があります。または、コンテナの変更によって要素参照が無効にされないコンテナを使用します(listまたはmultisetunordered_multiset汎用の場合dequeは、最後に挿入/削除します)。

または、ポインタのコピーをスレッドに渡すだけですか?!

于 2012-09-07T12:40:10.187 に答える
2
std::vector<HAS::TCPSocket*> sockets(MAXCONN);
...
sockets.push_back(sock);
std::thread handler(handleTCPClient, std::ref(sockets[socketCount++]));

そのコードはおかしく見えます。push_back()ベクトルは 4 つの null ポインターを保持し、その後に呼び出しの最後に追加される実際のポインターが続きます。スレッドは、必要な実際のポインターではなく、最初の null ポインターへの参照を取得します。

あなたは2つのことのいずれかを行うことができます.私の提案は、ベクトルのデフォルトのコンストラクターを使用reserve()し、push_backs. それは問題を解決するでしょう。または、要素を使用してベクトルを作成することもできますが、呼び出すのpush_back()ではなく、を使用operator[]して位置の要素を変更しsocketCountます。

于 2012-09-07T13:08:19.853 に答える