2011-11-12 9 views
-1

これは私の質問です。スレッドはとても混乱しています。スレッドが5つ、サイトが50か100以上あるとしましょう。だから私はスレッドについて学んだ限り、私はコンストラクタを作成(リンク:文字列)し、別のリンクで新しいスレッドを開始することができますが、私は解析する必要があるリンクの数と同じくらい多くのスレッドを作る必要がありますスレッド間で変数のリンクを共有するにはどうすればいいですか?スレッド1がリンクlistbox1.items [0]をダウンロードすると、数値0がダウンロードされ、次のスレッドはダウンロードして回答を得るべきか質問します。listbox1.items [1]終了する必要があるときにすべてのリンクをダウンロードするまで続きます。 誰でも私にどのようにこれを行うことができるかの簡単な例を教えてもらえますか?スレッドは私を殺しています:(Delphiのスレッドと変数

+1

...あなたが可能な無限ループシナリオを防ぐことを確認する必要があります。しかし、一般的にスレッディングの知識を磨く必要もあります。あなたはJoe Duffyの本「Concurrent Programming on Windows」を買って読んでいるよりずっと悪いことがあります。クイックで汚いアプローチのために、InterlockedIncrementを使用して、GetNextJobアプローチの一部としてタスクカウンタとしてインクリメントすることができます。しかし、実際には、これはOTLでは自明です。 –

+0

この質問に受け入れられた答えは、ロジックとサンプルコードのいくつかの有用な議論を持っています:http://stackoverflow.com/questions/2515036 – Argalatyr

+0

OTLはdelphi 7をサポートしていますか?スレッドでは10ページまたは15ページしかなく、ほとんどの場合、すべて同じことを伝えます。ありがとう –

答えて

2

critical sectionを設定するだけです。

これは、次のURLを読み取るコードセグメントの周りに設定する必要があります。これを行うには、通常、コードの先頭にセマフォを配置して、いつでも1つのスレッドしか入力できないようにします。セマフォはコードの最後にリセットされます。新しいスレッドごとにURLリストの有効期限が切れたと判断されると、終了します。

通常、セマフォはブール値ですが、たとえば、特定の数のスレッドがいつでも領域に入ることを許可する場合は、整数にすることができます。

あなたの場合は、単純にグローバルブール変数(すべてのスレッドに表示可能)、たとえば "fSemaphore"を設定することができます。

領域の先頭で、スレッドはフラグをチェックします。 falseの場合はtrueに設定され、領域に入る(次のURLを取得する)。 trueの場合、ループします。 (fSemaphoreではなく)までsleep(0)を繰り返します。 リージョンを終了すると、fSemaphore:= Falseに設定されます。

明らかに、あなたはあなたの最善の策は、[OTL](http://otl.17slon.com/)を使用することです

4

処理するURLのスレッドセーフリストとワーカースレッドの静的なサイズのプールをそれぞれリストから一度に取り出して処理します(ダウンロードと解析リスト内に未処理の項目がある限り、リスト内に見つかった新しいURLをループに追加します。リスト内に終了したURLを保持し、完了したとマークするだけで再帰を避けます。

+0

"リスト内の完成したURLを保持し、再帰を避けるために完了したものとしてマークしてください" - 私はこれを実際に避けるようにします。あなたはこれらのスレッドの多くを起動する予定であり、アプリは長時間実行される可能性があります。このリストが大きすぎるとあなたの記憶を食べてしまうかもしれません。私は通常、自分のスレッドを "FreeOnTerminate"にして、私が解放する直前に、それがフリーであることを親に知らせるカスタムイベント "OnFinished"をトリガーし、それをリストから削除します。 –

+0

@ JerryDodgeまあ、私はまだ何とか再帰を避けなければならないと思います。そうしないと、同じURLを何度も何度も処理することになります。 –

1

リクエストURI、結果、エラーメッセージ、URIアクセスに使用されるコンポーネントを除いてWebクエリに必要なものはすべて 'TURI'クラスですTObjectから降順で作成してください100個を作成して初期化し、プロデューサ - コンシューマキュー(TObjectQueue、TCriticalSection、セマフォはうまくいくはずです)。キューから空になるまでTURIインスタンスをループして処理するキューから広告を削除します。

処理されたTURIを使用する必要があるとは言わない - どこか自由にする必要がある。メインスレッドに通知したい場合は、完了したURIをPostMessageでメッセージハンドラで解放します。

スレッドを終了しますか?確かに、もしあなたが本当にしなければならない場合は、自殺を知らせるいくつかのオブジェクトをキューに入れます(NILかもしれません - スレッドはキューをポップした直後に 'assigned'をチェックできます)。このようなことをするとき、私は、アプリケーションの実行中にそれ以上のURIを処理する必要がなくてもスレッドを残しておきます。

悲しいことに、Delphiの例と、恐れている多くの教科書は、スレッドの制御を中断/再開するよりもはるかに多くなります(しないでください)。また、 'TThread.Synchronize'、 'TThread。 「WaitFor」と「TThread.OnTerminate」を選択します。あなたがそのような教科書を手に入れたら、それを外に持ち帰って燃やしてください。

関連する問題