46

私の初心者の質問に耐えてください。

ASP.NETとC#でghostscriptを使用してPDFをPNGに変換しようとしていました。ただし、ghostscriptはスレッドセーフではないことも読みました。だから私の質問は:

  1. 「ghostscriptはスレッドセーフではない」とは、実際にはどういう意味ですか?多くの同時ユーザーが同時にアクセスするライブASP.NET(aspx)Webアプリケーションで使用すると、どのような影響がありますか?

  2. また、別のサイトからghostscriptver。の主な機能を読んだ。8.63はマルチスレッドレンダリングです。これは、スレッドセーフの問題が解決されたことを意味しますか?ghostscriptスレッドは安全ですか?

  3. また、スレッドセーフであると思われるPDFTronのPDF2Imageも評価しています。しかし、CPUあたりのライセンスは安くはありません。「スレッドセーフ」と「安全ではない」のどちらに追加料金を支払う価値はありますか?

4

7 に答える 7

39

誰もが同意する正確な技術的定義を思い付くのは困難です。

非公式には、「スレッドセーフ」とは、単に「複数のスレッドから呼び出されたときに適切に動作する」ことを意味します。複数のスレッドから呼び出されたときに、オブジェクトがクラッシュしたり、クレイジーな結果を生成したりすることはありません。

特定のオブジェクトを含むマルチスレッドプログラミングを実行する場合に実際に回答する必要がある質問は、「オブジェクトに期待されるスレッドモデルは何ですか?」です。

さまざまなスレッドモデルがたくさんあります。たとえば、「フリースレッド」モデルは、「任意のスレッドから好きなことを実行します。オブジェクトがそれを処理します」です。これは、対処するのが最も簡単なモデルであり、オブジェクトプロバイダーが提供するのが最も難しいモデルです。

スペクトルのもう一方の端には、「シングルスレッド」モデルがあります。すべてのオブジェクトのすべてのインスタンスは、単一のスレッド、期間からアクセスする必要があります。

そして、真ん中にたくさんのものがあります。「アパートメントスレッド」モデルは、「2つの異なるスレッドで2つのインスタンスを作成できますが、インスタンスの作成に使用するスレッドは、そのインスタンスのメソッドを呼び出すために常に使用する必要があるスレッドです」です。

「レンタルスレッド」モデルは、「2つの異なるスレッドで1つのインスタンスを呼び出すことができますが、2つのスレッドが同時に呼び出さないようにする責任があります」です。

等々。オブジェクトに対してスレッドコードを記述しようとする前に、オブジェクトが期待するスレッドモデルを確認してください。

于 2010-03-09T21:10:57.943 に答える
25

たとえば、コレクションが脅威ではない場合、次のようになります。

var myDic = new Dictionary<string, string>();

マルチスレッド環境では、これは以下をスローします:

string s = null;
if (!myDic.TryGetValue("keyName", out s)) {
    s = new string('#', 10);
    myDic.Add("keyName", s);
}

1つのスレッドがKeyValuePairをディクショナリmyDicに追加しようとしているときに、別のスレッドがTryGetValue()を実行する場合があります。コレクションの読み取りと書き込みを同時に行うことはできないため、例外が発生します。

ただし、一方で、これを試してみると:

// Other threads will wait here until the variable myDic gets unlocked from the preceding thread that has locked it.
lock (myDic) {
    string s = null;
    if (!myDic.TryGetValue("keyName", out s)) {
        s = new string('#', 10);
        myDic.Add("keyName", s);
    }
} // The first thread that locked the myDic variable will now release the lock so that other threads will be able to work with the variable.

次に、突然、同じ「keyName」キー値を取得しようとする2番目のスレッドは、最初のスレッドがすでに追加したので、それをディクショナリに追加する必要がなくなります。

つまり、スレッドセーフとは、オブジェクトが複数のスレッドによる同時使用をサポートすること、またはスレッドセーフを気にすることなくスレッドを適切にロックすることを意味します。

2.GhostScriptがスレッドセーフになったとは思いません。主に複数のスレッドを使用してタスクを実行しているため、パフォーマンスが向上します。それだけです。

3.予算と要件によっては、価値がある場合があります。しかし、ラッパーを中心に構築する場合は、おそらくそれが便利な場合にのみlock()を実行できます。または、マルチスレッドを自分で使用しない場合は、スレッドセーフにお金を払う価値はありません。これは、アプリケーションがマルチスレッドを使用している場合にのみ、ライブラリがスレッドセーフでないという結果に苦しむことがないことを意味します。あなたが本当にマルチスプレッドでない限り、スレッドセーフなライブラリにお金を払う価値はありません。

于 2010-03-09T21:04:10.347 に答える
11

私はGhostscript開発者であり、スレッドセーフに関する一般的な理論を繰り返すことはありません。
GSをスレッドセーフにして、単一のプロセス内からgsapi_new_instanceを使用して複数の「インスタンス」を作成できるようにするために取り組んできましたが、これを満足のいくように完了していません(これには、QAテストが含まれます)。
ただし、グラフィックライブラリはスレッドセーフであり、マルチスレッドレンダリングはこれに依存して、複数のスレッドを生成し、ディスプレイリストからバンドを並列にレンダリングできるようにします。マルチスレッドレンダリングは多くのQAテストを受けており、マルチコアCPUのパフォーマンスを向上させるために多くの商用ライセンシーによって使用されています。

GSの複数のインスタンスを最終的にサポートするときに発表することは間違いありません。複数のインスタンスを必要とするアプリケーションから現在のGSを使用したいほとんどの人は、GSがスレッドセーフである必要がないように、インスタンスごとに個別のプロセスを生成します。GSは、引数リストオプションによって決定されたジョブを実行するか、I / Oをプロセスとの間でパイプ処理して、データを提供し、出力を収集することができます。

于 2011-06-26T04:41:43.203 に答える
10

1)複数のスレッド間で同じGhostscriptオブジェクトまたはフィールドを共有すると、クラッシュすることを意味します。例えば:

private GhostScript someGSObject = new GhostScript();
...
// Uh oh, 2 threads using shared memory. This can crash!
thread1.Use(someGSObject);
thread2.Use(someGSObject);

2)私はそうは思いません-マルチスレッドレンダリングは、GSが内部的に複数のスレッドを使用してレンダリングしていることを示唆しています。GSが複数のスレッドからの使用に対して安全ではないという問題には対処していません。

3)そこに質問はありますか?

GhostScriptスレッドを安全にするには、一度に1つのスレッドだけがそれにアクセスしていることを確認してください。これは、ロックを介して行うことができます。

lock(someObject)
{
   thread1.Use(someGSObject);
}
lock(someObject)
{
   thread2.Use(someGSObject);
}
于 2010-03-09T20:47:25.513 に答える
3

シェルオブジェクトからghostscriptを使用している場合(つまり、ファイルを処理するためにコマンドラインを実行している場合)、実行中のすべてのインスタンスがサーバー上で異なるプロセスになるため、スレッドの問題に巻き込まれることはありません。注意が必要なのは、PDFを処理するためにC#から使用しているdllがある場合、2つのスレッドが同じコードを同時に実行しないように、そのコードを同期する必要があります。

于 2010-03-09T20:52:07.530 に答える
2
  1. スレッドセーフとは、基本的に、複数のスレッドからアクセスされた場合でも、コードの一部が正しく機能することを意味します。スレッド化されたアプリケーションで非スレッドセーフコードを使用すると、複数の問題が発生する可能性があります。最も一般的な問題はデッドロックです。ただし、スレッドの問題はデバッグが難しいことで有名なため、さらに多くの問題になる可能性のある、はるかに悪質な問題(競合状態)があります。

  2. いいえ。マルチスレッドレンダリングとは、GSがスレッドを使用してレンダリングするため、GSがより高速にレンダリングできることを意味します(理論的には、とにかく、実際には常に正しいとは限りません)。

  3. これは、レンダラーを何に使用するかによって異なります。複数のスレッドを使用してアプリケーションにアクセスする場合は、はい、スレッドセーフであることを心配する必要があります。そうでなければ、それは大したことではありません。

于 2010-03-09T20:51:31.730 に答える
1

一般に、これはあいまいな用語です。

スレッドセーフは、共有データを正しく同期できる概念レベルである可能性があります。これは通常、ライブラリライターが意味するものです。

場合によっては、並行性が言語レベルで定義されていることを意味します。つまり、言語のメモリモデルは並行性をサポートします。これはトリッキーです!なぜなら、ライブラリライターとして、並行ライブラリを作成することはできないからです。言語には、使用する必要のある多くの重要なプリミティブに対する保証がないからです。これは、ライブラリユーザーよりもコンパイラライターに関係します。その意味で、C#はスレッドセーフです。

私はあなたの質問に直接答えなかったことを知っていますが、それがお役に立てば幸いです。

于 2010-03-09T20:50:30.547 に答える