3

関数を公開するPython用のカスタムc++モジュールがあり、その一部はTBB(tbb21_015oss)を使用して処理を高速化します。

これまで、Win32環境でPython(2.6.2)からTBBアクセラレーション関数を呼び出すときに問題はありませんでした。

しかし今、Pythonスレッド(threading.Threadクラスを使用して作成された)からそのような関数を呼び出すときに問題が発生します-同じ関数を呼び出している間、メインのPythonスレッドからは正常に機能します。

関数を呼び出すと、アプリケーションがクラッシュし、次のメッセージが表示されます。

First-chance exception at 0x03522e96 in python.exe:
0xC0000005: Access violation reading location 0x000000c8.

TBB.dllのベースアドレスは0x03510000であり、MSVC 2005デバッガーによると、クラッシュはTBBの「parallel_for.h」からのコードで発生しますstatic void start_for::run( const Range& range, const Body& body, const Partitioner& partitioner )

start_for& a = *new(task::allocate_root(context)) start_for(range,body,const_cast<Partitioner&>(partitioner));

逆参照されているNULLポインターがあるようです。

FWIW、TBBは、遅延初期化メカニズムを使用して初期化されます。

// at 'global' scope
tbb::task_scheduler_init g_tbbinit(tbb::task_scheduler_init::deferred);  
...
// in a function
g_tbbinit.initialize();

これを機能させる方法はありますか?たとえば、TBBを「カスタム」スレッドから呼び出せるようにするには、特定の初期化が必要ですか?

4

1 に答える 1

2

TBB 2.1では、TBBを使用する各外部スレッドは、最初に独自のtask_scheduler_initオブジェクトを作成する必要があります。単一のグローバルオブジェクトは機能しません。

TBBの新しいバージョンでは、この要件が緩和されました。現在、このようなスレッド固有の初期化オブジェクトは、存在しない場合は暗黙的に作成されます。

tbb.dllをより新しいバージョンに機械的に置き換えることが役立つかどうか試してみてください。前述のC++モジュールを最新バージョンのTBBで再コンパイルすると、さらに優れたものになります。モジュールを作り直して、それを呼び出すスレッドごとに個別にTBBを初期化する(古いバージョンでも機能するようにする)場合は、設計上の制約で禁止されていない場合でも、意味があります。

于 2011-05-11T09:52:51.467 に答える