2016-04-01 8 views
4

私はマルチスレッドのWebクローラーを構築しています。すべてのプロセスがアクセスできるマップを作成するにはどうすればよいですか?

最初にnのhrefリンクを取得し、いくつかのデータを解析するスレッドを起動します。次に、それらのリンクを他のスレッドがアクセスできるVisitedリストに追加し、プログラムが完了したときに印刷されるグローバルマップにデータを追加する必要があります。その後、スレッドは新しいn新しいスレッドをすべて起動します。

すべてのスレッドがアクセス可能な訪問済みサイトのグローバルリストと、すべてのスレッドが書き込み可能なグローバルマップを設定する方法を教えてください。

答えて

1

erlang/elixirは、スレッドではなくプロセスを使用しています。要素のリストを考えると

、一般的なアプローチ:

  • processedと呼ばれる空のリストがETS、DETS、mnesiaまたはいくつかのDBに保存されます。
  • 新しいリストの要素は、processedリストに対してフィルタリングされるため、タスクは不必要に繰り返されません。
  • フィルタリングされたリストの各要素に対して、タスクが実行され(プロセスが生成されます)、必要なデータのマップを返す各要素が機能します。 Task moduleTask.async/1およびTask.yield_many/2を参考にしてください。すべてのタスクが返されるかもたらしたら
    1. すべてのマップまたはマップ内のデータの一部がマージされ、場合、必要に応じて、適切な/ /持続することができます。
    2. タスクがクラッシュしたりタイムアウトしなかった要素は、DB内のprocessedリストに追加されます。
  • クラッシュまたはタイムアウトの処理が異なる可能性があります。

8

プロセス間でデータを共有することはできません。つまり、情報を共有できないというわけではありません。

通常の方法は、このジョブを担当する特別なプロセス(サーバー)を使用することです。状態を維持する。あなたのケースでは訪問されたリンクのリスト。

別の方法は、プロセス間で情報を共有するように設計されたETS(またはMnesiaデータベースビルドETS)を使用することです。

+0

通常、単純に一部の状態をラップするプロセスはエージェントに基づいています。あなたはそれをメッセージを送信して、状態を問い合わせるか、または取得することができます。ドキュメントについてはhttp://elixir-lang.org/getting-started/mix-otp/agent.htmlを参照してください(はい、私はリンク貼り付けがあまりにも嫌なので、ちょうどコメント:-)) – cdegroot

関連する問題