2

メインスレッドで使用し、後で子スレッドでpthread_create()使用しているアプリケーションがあります。pthread_detach()pthread_exit()

約 54pthread_create()回の呼び出しの後、それぞれが後続の呼び出しとペアにpthread_detach()なりpthread_exit()pthread_create()失敗します。ENOMEM「メモリ不足」の失敗です。

pthread_exit()古いスレッドのメモリが解放されず、アプリケーションでメモリ リークが発生し、最終的に不足する原因は何ですか?

これは Linux Centos 5 64 ビットで実行されていますが、32 ビットで構築されたアプリケーションです。

pthread_create()と の両方を呼び出すスレッドを作成するコードを次に示しますpthread_detach()

int
_createThread()
{
  pthread_attr_t attr;
  int return_val;

  return_val = setupMutex(_Mtx());

  if (return_val != 0) {
    return return_val;
  }

  return_val = setupCond(_StartCond());

  if (return_val != 0) {
    return return_val;
  }

  return_val = setupCond(_EndCond());

  if (return_val != 0) {
    return return_val;
  }

  return_val = pthread_attr_init(&attr);

  if (return_val != 0) {
    return -1;
  }

  size_t stackSize = 1024 * 1024 * 64; // Our default stack size 64MB.

  return_val = pthread_attr_setstacksize(&attr, stackSize);

  if (return_val != 0) {
    return -1;
  }

  int tries = 0;

 retry:
  // _initialize() gets called by the thread once it is created.
  return_val = pthread_create(&_threadId, &attr,
                              (void *(*)(void *))_initialize,
                              (void *)this);

  if (return_val != 0) {
    if (return_val == EAGAIN) {
      if (++tries < 10) {
        Exit::deferredWarning(Exit::eagainThread);
        goto retry;
      }
    }
    return -1;
  }

  return_val = pthread_attr_destroy(&attr);

  if (return_val != 0) {
    return -1;
  }

  return_val = pthread_detach(_threadId);

  if (return_val != 0) {
    return -1;
  }

  // Wait for the new thread to finish starting up.
  return_val = waitOnCond(_Mtx(), _EndCond(), &_endCount, 10 /* timeout */, 0,
                          "_createThread-end");

  if (return_val != 0) {
    return -1;
  }

  return 0;
}

void
_exitThread()
{
  (void) releaseCond(_Mtx(), _EndCond(), &_endCount, "_exitThread-end");
  pthread_exit(NULL);
}
4

4 に答える 4

4

pthread_exitの前にpthread_joinを呼び出して、スレッドが終了する前にクリーンアップできるようにします。

于 2010-12-25T16:34:49.053 に答える
2

説明はpthread_createの man ページにあります。

切り離されたスレッドが終了すると、そのリソースは自動的に解放されてシステムに戻されます。別のスレッドが終了したスレッドに参加する必要はありません。

したがって、それを切り離したり結合したりしないと、リソースが失われ、最終的に ENOMEM が発生します。

スレッドを切り離すか、親スレッドから結合する必要があります。

于 2016-08-25T08:00:47.123 に答える
1

ウィル、私が間違っていたように見えるので、古い回答を削除しました。この線に沿って、質問がありますENOMEM。私の回答で示したように、「errno」をチェックしましたか?はルールの例外であるためpthread_create、errno を設定しません。代わりに、結果としてエラーが返されます。

失敗理由を取得する正しい方法:

int err = pthread_create(...);
if(err)
{
    perror( "Error creating thread" );
    printf( "Error: %s\n", strerror( err ) );
    return false;
}

私が質問する理由はpthread_create、ENOMEM で決して失敗しないからです! メモリがない場合はpthread_createを返しEAGAINます。EAGAIN と ENOMEM の情報については、 http: //sourceware.org/ml/glibc-bugs/2007-11/msg00007.html を参照してください。

編集

明らかな質問: システムには十分な空きメモリが残っていますよね?

于 2010-12-28T15:45:56.247 に答える
0

pthread_join()ユースケースで参加がうまくいかpthread_detatch()ない場合は、電話してください。

このエラーは、終了したすべてのスレッドの終了コードをライブラリが保存し、 経由で返されるのを待っているために発生しますpthread_join()。または、スレッドの終了コードを気にしない場合は、pthread_detatch()作成後に呼び出します。これは、戻りコードを気にしないことを API に伝えるため、戻りコードを保存する必要はありません。

于 2016-02-15T04:53:42.443 に答える