- 締切済み
grep でパラレル検索するには
あるディレクトリいかに置かれているソースコードの中で特定のパターン (文字列) を含むファイルの一覧を取得するのに grep を使って検索してい るのですが、もう少しよい方法がないかと試行錯誤しています。 [現行法] find . -type f | \ while read line; grep -qP pattern "$line" && echo $line; done そこで、使用しているサーバのCPU 数が8であることに目を付け、マルチ プロセスもしくはマルチスレッドの仕組みを用いて8多重でgrepを実行で きる仕組みを考えています。 最初に考えたのは以下のような方法です。 ・pthread を利用する。 ・各レッドで system 関数を使用して grep を実行する。 ・子プロセスは標準入力をパイプから受け取るようにする。 ・検索対象となるファイル一覧の読み込みは mutex を用いて制御する。 →system 関数はシェル経由で grep をコールするようで、オーバーヘッド が気になるなどの理由により却下。 次に考えたのは以下のような方法です。 ・pthread を利用する。 ・各スレッドで fork し、子プロセスで grep を実行する (exec)。 ・子プロセスは標準入力をパイプから受け取るようにする。 ・検索対象となるファイル一覧の読み込みは mutex を用いて制御する。 →デッドロックの問題が解決できずに断念。 pthread で fork を使う場合は直ぐに exec するようにしないとデッド ロックする可能性があるという記事をネット上で見つけました (標準入力 をパイプから受け取るようにする処理があるため直ぐには exec できな い)。で、実際にもそのようになってしまいました。 そして、最終的に考えているのが以下のような方法です。 ・fork を利用する。 ・各プロセスでさらに fork し、孫プロセスで grep を実行する (exec)。 ・孫プロセスは標準入力をパイプから受け取るようにする。 ・検索対象となるファイル一覧の読み込みはセマフォを用いて制御する。 でも、本当にこのようにマルチプロセス+セマフォを使う方法でしか 「grep でパラレル検索」を実現することはできないのでしょうか? pthread で実現することには失敗してしまいましたが、もう少し改良して 成功できないかと考えているのですが・・・。 (かと言って、あちこち mutex でロックしてしまうと、せっかくのスレッ ドが生かされない?)
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- notnot
- ベストアンサー率47% (4900/10358)
多重での検索をたびたびしたくなるような使い方なのであれば、namazuなどでデータベース化するアプローチもあるかと思います。
- SAYKA
- ベストアンサー率34% (944/2776)
http://www.google.com/search?q=%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%20linux&hl=ja&lr= そこまでするなら正規表現ライブラリを呼ぶ方が良いんじゃない?
お礼
そういう手もありましたね。 いただいた回答を見たとき、pcre とか regex を使うことを最初に思い つきましたが、grep そのものをライブラリ化しても構わないんですね。 そうすれば fork しなくても複数のファイルを検索できますね。 それも検討してみます。
補足
最初の説明が不十分だったと思うので、 やりたいことのイメージを示しますと、 ファイルまたは標準出力 ------ filename1 filename2 filename3 filename4 filename5 filename6 filename7 filename8 filename9 ------ ↓(標準) 入力 親プロセス (スレッド) ↓ ↓ ↓ ↓(振り分け) filename1 filename2 filename3 filename4 filename5 filename7 filename8 filename6 filename9 ↓ ↓ ↓ ↓標準入力 (パイプ) grep grep grep grep (この場合、4多重) パターンにマッチしたファイル名を表示 (順番は入力順でなくても可)
お礼
質問の後に fork のみを使用した形でプログラムの作成自体には 成功しましたが、grep の -l オプションを見落としていました。 検索に時間がかかるのは grep を何度もコールするからであり、 find . -type f | xargs grep -l pattern で解決しました。(grep を何度も呼ぶパラレル検索よりもよっぽど速い) ご回答ありがとうございました。