6

kernel 2.4.20と を実行している 2 つのシステムでいくつかのコードを使用していますkernel 2.4.38。彼らは両方とも持っていgcc 3.2.2ますglibc 2.3.2

では、 pthread_tkernel 2.4.38ハンドルは再利用されていません。高負荷テストでは、ハンドルが に達するとアプリケーションがクラッシュします0xFFFFFFFF

(IT がネットワーク ポート スキャナーを使用する展開でアプリがクラッシュするため、そもそもこれを疑っています。スレッドはソケット接続を処理するために作成されます)。

この簡単な例は、問題を再現します。

void* ThreadProc(void* param)
{
    usleep(10000);
    printf(" Thread 0x%x\n", (unsigned int)pthread_self());
    usleep(10000);
    return NULL;
}

int main(int argc, char* argv[])
{
    pthread_t sThread;

    while(1)
    {
      pthread_create(&sThread, NULL, ThreadProc, NULL); 
      printf("Created 0x%x\n", (unsigned int)sThread);  
      pthread_join(sThread, NULL);
    };

    return 0;
}

2.4.20 未満:

    Created 0x40838cc0
     Thread 0x40838cc0
    Created 0x40838cc0
     Thread 0x40838cc0
    Created 0x40838cc0
     Thread 0x40838cc0
...and on and on...

2.4.36 未満:

    Created 0x4002
     Thread 0x4002
    Created 0x8002
     Thread 0x8002
    Created 0xc002
     Thread 0xc002
...keeps growing...

kernel 2.4.36ハンドルをリサイクルするにはどうすればよいですか? 残念ながら、カーネルを簡単に変更することはできません。ありがとう!

4

2 に答える 2

4

あなたの観察が正しければ、考えられる解決策は 2 つしかありません。

また

  1. カーネルをアップグレードします。これは、実行できる場合と実行できない場合があります。
  2. アプリケーション内のスレッドをリサイクルします。

オプション 2 は、カーネルが正しく動作していない場合でも実行できるものです。使用されていないときにスリープ状態のままになるスレッドのプールを保持できます。スレッド プールは、広く知られているソフトウェア エンジニアリング パターンです ( http://en.wikipedia.org/wiki/Thread_pool_patternを参照)。これはおそらくあなたにとってより良い解決策です。

于 2012-07-05T13:17:36.610 に答える
0

負荷テストでスレッドを適切に結合していなかったことが判明しました。

負荷テストを再度実行すると、スレッド ハンドルが 0xFFFFF002 に到達し、その後 0x1002 にロールオーバーして問題なく実行されました。

話の教訓: スレッドが結合または分離されていることを確認してください。

于 2012-07-06T11:47:58.393 に答える