6

多くのライブラリとリンクするプログラムがあります。プロファイラーでアプリケーションを実行したところ、ネットワーク リクエストの後、ほとんどの時間が「待機」状態で費やされていることがわかりました。これらのリクエストはsleeping_function()、外部ライブラリから呼び出した私のコードの効果です。この関数を何度も実行するループで呼び出すため、すべての待機時間は合計すると膨大な量になります。

を変更できないためsleeping_function()、いくつかのスレッドを開始して、ループのいくつかの反復を並行して実行したいと考えています。問題は、この関数が内部的にいくつかのグローバル変数を使用していることです。

SunOS のリンカーに、特定のライブラリをリンクして、それらのすべての変数をスレッド ローカル ストレージに配置するように指示する方法はありますか?

4

2 に答える 2

2

リンカーだけでこれを達成できるとは思いませんが、C のコードで何かを動作させることができるかもしれません。

問題は、既にロードされているライブラリをロードする呼び出しが、新しいコピーをロードする代わりに、既にロードされているインスタンスへの参照を返すことです。dlopenLoadLibraryのドキュメントをざっと見てみると、少なくともイメージを実行する準備をしたい場合は、同じライブラリを複数回ロードする方法がないことが確認されているようです。これを回避する 1 つの方法は、OS が同じライブラリであることを認識しないようにすることです。これを行うには、ファイルのコピーを作成できます。

いくつかの疑似コード。 への呼び出しを へsleeping_functionの呼び出しに置き換えるだけcall_sleeping_function_thread_safeです。

char *shared_lib_name

void sleeping_function_thread_init(char *lib_name);

void call_sleeping_function_thread_safe()
{
  void *lib_handle;
  pthread_t pthread;
  new_file_name = make_copy_of_file(shared_lib_name);

  pthread_create(&pthread, NULL, sleeping_function_thread_init, new_file_name);
}

void sleeping_function_thread_init(char *lib_name)
{
  void *lib_handle;
  void (*)() sleeping_function;

  lib_handle = dlopen(lib_name, RTLD_LOCAL);
  sleeping_function = dlsym(lib_handle, "sleeping_function")
  while (...)
    sleeping_function;
  dlclose(lib_handle);
  delete_file(lib_name);      
}

Windows の場合は、次のようになりdlopenます。ただし、基本的な考え方は引き続き機能します。LoadLibrarydlsymGetProcAddress

于 2010-09-15T14:07:45.853 に答える
0

一般に、これは悪い考えです。スレッドセーフでないライブラリがマルチスレッド環境で実行できない問題は、グローバル データだけではありません。

一例として、ライブラリに、常に単一のハードコードされたアドレスにマップされるメモリ マップ ファイルを指すグローバル変数があるとします。この場合、あなたの手法では、スレッドごとに 1 つのグローバル変数がありますが、それらはすべて同じメモリ位置を指し、マルチスレッド アクセスによって破棄されます。

于 2010-09-15T14:14:49.770 に答える