2

スレッドごとに 1 つの Tcl インタープリターを作成しようとしているときに、クラッシュに直面しています。Linux rh6 で TCL バージョン 8.5.9 を使用しています。ある種のメモリ破損のように見えるたびに、さまざまな機能でクラッシュします。ネットを通過することは有効なアプローチのようです。誰かが同様の問題に直面しましたか? マルチスレッドでの Tcl の使用には、何らかの特別なサポートが必要ですか?

以下は、tcl バージョン 8.5.9 でクラッシュを引き起こす小さなプログラムです。

#include <tcl.h>
#include <pthread.h>

void* run (void*)
{
        Tcl_Interp *interp =  Tcl_CreateInterp();
        sleep(1);
        Tcl_DeleteInterp(interp);
}

main ()
{
        pthread_t t1, t2;

        pthread_create(&t1, NULL, run, NULL);
        pthread_create(&t2, NULL, run, NULL);

        pthread_join (t1, NULL);
        pthread_join (t2, NULL);
}
4

2 に答える 2

1

ライブラリのスレッド対応ビルドを使用する必要があります。

スレッドを有効にせずにビルドすると、Tcl はメモリ管理などの場所でかなりの量のグローバル静的データを内部的に使用します。それはかなり普及しています。最終的にはうまくいくかもしれませんが (すべての初期化とセットアップを 1 つのスレッド内で行う場合)、それはあまりお勧めできません。あなたの場合、物事が奇妙な方法でクラッシュすることは、まったく驚くべきことではありません。

Tcl のスレッド対応ビルドを使用すると、グローバルな静的データはすべて、スレッド固有のデータまたはミューテックスで保護された適切なグローバル データに変換されます。これにより、一度に多くのスレッドから Tcl を使用できるようになります。ただし、特定Tcl_Interpのものは、それを作成したスレッドにバインドされます (多くのスレッド固有のデータを使用するため)。あなたの場合、それは問題ありません。インタープリターはスレッドごとのエンティティです。

(まあ、Tcl ライブラリ自体を初期化するための呼び出しも追加する場合は、一度だけ実行する必要があります。これらのスレッドを作成する前にTcl_FindExecutable(NULL);内部に入れます。)main()


Tcl 8.5 は、下位互換性の理由から、Unix ではデフォルトでスレッド対応ではありませんでした — Windows と Mac OS X では、低レベルのイベントを処理する方法が異なるため、スレッド対応でした — しかし、これは 8.6 で変更されました。RH6でスレッド対応ビルドを取得する方法がわかりません(ソースから自分でビルドする以外は簡単です)。

于 2013-10-04T10:48:01.060 に答える
1

デフォルトの Tcl ライブラリはビルド スレッド対応ではありません。(まあ、8.5.9 ではなく、8.6 です)。

それで、tcl lib がスレッド対応にビルドされていることを確認しましたか?

ライブラリに対してビルドされている場合はtclsh、次を実行するだけです。

% parray ::tcl_platform
::tcl_platform(byteOrder)     = littleEndian
::tcl_platform(machine)       = intel
::tcl_platform(os)            = Windows NT
::tcl_platform(osVersion)     = 6.2
::tcl_platform(pathSeparator) = ;
::tcl_platform(platform)      = windows
::tcl_platform(pointerSize)   = 4
::tcl_platform(threaded)      = 1
::tcl_platform(wordSize)      = 4

が 0 の場合::tcl_platform(threaded)、ビルドはスレッド対応ではありません。--enable-threadsconfigure スクリプトに渡して、スレッドをサポートするバージョンをビルドする必要があります。

正しい定義を使用して、tcl.h からスレッド対応マクロが必要であることを宣言しましたか? コンパイラの呼び出しに追加する必要があり-DTCL_THREADS ます。そうしないと、ロック マクロがノーオペレーションとしてコンパイルされます。

于 2013-10-03T19:19:10.140 に答える