23

次の PHP コードは、約 3.5 秒のランタイムを返します (複数回測定して平均)。

$starttime = microtime(true);
exec('/usr/local/bin/convert 1.pdf -density 200 -quality 85% 1.jpg');
$endtime = microtime(true);
$time_taken = $endtime-$starttime;

ssh 端末で同じコマンドを実行すると、実行時間が約 0.6 秒に短縮されます (コマンド ライン ツールで測定time)。

imagemagick ライブラリのバージョンは

Version: ImageMagick 6.7.0-10 2012-12-18 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2011 ImageMagick Studio LLC
Features: OpenMP

この時差の理由は何でしょうか?

ここでのスタックオーバーフローに関する同様の質問に対する 1 つの回答は、スレッド/シェルを開始する必要がある Web サーバーからオーバーヘッドが発生するというものでした。これが本当の理由でしょうか?スレッドは軽量で、開始/終了にまったく時間がかからないと思いました。

呼び出す前にexec、imagemagick が使用するスレッドのexec('env MAGICK_THREAD_LIMIT=1');. 設定した値に関係なく、PHP のランタイムはあまり変わりませんMAGICK_THREAD_LIMIT。とにかく、コマンドライン実行のランタイムは問題ないので、このバージョンでは OpenMP にバグはないようです。

上記のコマンドの実行時間を改善する方法についての提案は大歓迎です。

ご助力ありがとうございます。

4

6 に答える 6

15

キーボードまたはsshを介してUnixマシンにログインすると、シェルの新しいインスタンスが作成されます。シェルは通常、/bin/shまたはのようなもの/bin/bashです。シェルを使用すると、コマンドを実行できます。

を使用するexec()と、シェルの新しいインスタンスも作成されます。そのインスタンスは、送信したコマンドを実行してから終了します。

シェルコマンドの新しいインスタンスを作成すると、独自の環境変数があります。したがって、これを行う場合:

exec('env MAGICK_THREAD_LIMIT=1');
exec('/usr/local/bin/convert 1.pdf -density 200 -quality 85% 1.jpg');

次に、2つのシェルを作成すると、最初のシェルの設定が2番目のシェルに到達することはありません。2番目のシェルで環境変数を取得するには、次のようなものが必要です。

exec('env MAGICK_THREAD_LIMIT=1; /usr/local/bin/convert 1.pdf -density 200 -quality 85% 1.jpg');

シェル自体が問題である可能性があると思われる場合は、シェルの作成に時間がかかりすぎるため、ほとんど時間がかからないことがわかっているものでテストしてください。

$starttime = microtime(true);
exec('echo hi');
$endtime = microtime(true);
$time_taken = $endtime-$starttime;

その時点で、シェルのインスタンス化を高速化する方法を見つけようとする必要があります。

お役に立てれば!

于 2013-01-11T13:04:54.663 に答える
6

@Philippは、SSHがあり、サーバーがへのアクセスを許可exec()しているため、マシンへの完全なルートアクセスも持っていると想定します。

単一ファイルの処理に推奨

マシンへのルート アクセス権があるということは、/etc/php5/php.iniメモリ制限の設定を変更できることを意味します。

に直接アクセスしなくても、プロジェクト ディレクトリに新しいファイルを作成することで、サーバーがディレクティブの/etc/php5/php.iniオーバーライドをサポートしているかどうかを確認できます。php.iniphp.ini

.htaccessオーバーライドが許可されていない場合でも、 if AllowOverrideisからメモリ設定を変更できますAll

メモリ制限を変更するもう 1 つの方法は、.php を使用して PHP ランタイム中に設定することini_set('memory_limit', 256);です。

バッチファイル処理に推奨

convert を介して実行することの唯一の利点は、結果を取得して非同期で実行するexec()予定がない場合です。exec()

exec('convert --your-convert-options > /dev/null 2>/dev/null &');

上記のアプローチは通常、多くのファイルをバッチ処理しようとしていて、それらが処理を完了するのを待ちたくない場合、およびそれぞれが処理されたことに関する確認を必要としない場合に役立ちます。

パフォーマンスノート

上記のコードを使用して単一のファイルを処理するためにexec実行するasyncと、PHP 内で GD/Imagick を使用するよりも多くのプロセッサ時間とより多くのメモリが消費されます。時間/メモリは、PHP プロセスに影響を与えない別のプロセスによって使用されますが (サイトの移動が速くなったとビジターに感じさせます)、メモリ消費が存在し、カウントされる多くの接続を処理する場合.

于 2013-01-11T12:38:40.967 に答える
2

phpを呼び出すとexec、スレッドは作成されず、新しい子プロセスが作成されます。新しいプロセスの作成は大きなオーバーヘッドです。

ただし、ssh で接続する場合は、実行するコマンドを渡すだけです。あなたはそのプログラムの所有者ではないため、接続したユーザーとして実行されます。execPHPを実行しているユーザー向け。

于 2013-01-11T12:11:53.467 に答える