私は同時に複数のクライアントからの接続を許可するサーバーを作成しています。新しい接続ごとに新しいスレッドを作成します。クライアントはこのスレッドでサーバーと通信します。クライアントがサーバから切断されたときに、スレッドのメモリをサーバプロセスに割り振り解除する必要があります。C++スレッドが末尾で自分自身を削除する
問題は「スレッド自体を削除しようとする」ときです。
私の問題を説明するために少しコードを書いています。クラスCは新しい接続を表します。私はすべての接続に対してこのクラスの新しいオブジェクトを動的に作成します。機能のアクションは、問題を説明するために自発的に簡素化されています。
#include <thread>
#include <iostream>
#include <mutex>
#include <chrono>
using namespace std;
mutex m;
class C {
thread *t;
static void action(int n, C* obj) {
for (int i = 0; i < 10; i++) {
m.lock();
cout << "i:" << i << ", n:" << n << endl;
m.unlock();
}
delete(obj);
}
public:
C() : t(nullptr) {}
~C() {
delete(t); // Work if I comment this line
}
void launch() {
static int i = 0;
t = new thread(action, i++, this);
}
};
int main() {
C *c1 = new C();
c1->launch();
this_thread::sleep_for(chrono::seconds(5));
return 0;
}
私の英語のために申し訳ありませんが、私はそれを学んでいます。
なぜポインタを使用していますか?あなたは、あなたからのクリーンアップを必要としない自動オブジェクトでこれをすべて行うことができます。 – NathanOliver
@LightnessRacesinOrbitこれは* C++ではなく、C#です。オリーブ:デモンストレーションされたコードでは、 'new'やポインタの必要はありません。 'namespace std;を使用しないでください。'、 'std'はあまりにも多くのシンボルを含んでいます。 – Yakk
新しい接続ごとに新しいスレッドを作成するのではなく、スレッド_pool_を使用することを検討してください。あなたが使用できる良いスレッドプールの実装があるかどうかを知るには十分なC++を知りませんが、単純な考え方です:_tasks_のブロックキューがあります(この場合、各タスクは待機中のクライアントを表すオブジェクトですサーブしてください)、キューからタスクを永久にループしようとするループがいくつかあります。スレッドがタスクを獲得すると、スレッドはタスクを実行する(すなわち、それはクライアントに役立ちます)、死ぬのではなく、次のタスクを待つために戻ってきます。 –