3

時間がかかるタスクを実行している PHP ページがあり、同時に同じサイトから別のページを読み込もうとすると、最初のページがタイムアウトするまでそのページは読み込まれません。たとえば、タイムアウトが 60 秒に設定されている場合、ロード/タイムアウトに時間がかかっていたページの 60 秒後まで、他のページをロードできません。私の知る限り、これは予想される動作です。

私が把握しようとしているのは、上記の状況を作成する誤った/長い読み込み PHP スクリプトが同じネットワーク上の他の人にも影響を与えるかどうかです。私は個人的にはブラウザの問題だと思っていました(つまり、http://somesite.com/myscript.phpをクロムにロードし、バックグラウンドで魔法のように動作し始めた場合、http://somesite.com/をロードできませんでしたタイムアウトになるまでmyscript2.phpを読み込んでいましたが、そのページを Firefox で読み込むことができました)。しかし、タイムアウトは同じネットワーク (IP アドレス?) 上のすべての人に発生するという矛盾した声明を聞いたことがあります。

私のスクリプトは、sage からインポートされた一部のデータで動作し、実行にかなりの時間がかかります - 終了する前にタイムアウトになることがあります (つまり、sage のインポートが 1 週間にわたってクラッシュした場合)。 . これが実行されている間、オフィスの他のスタッフがサイトにアクセスできなくなるのではないかと心配しています.

4

2 に答える 2

3

あなたがここで抱えている問題は、実際には (私は推測していますが) sessionsを使用しているという事実に関連しています。これは少しストレッチかもしれませんが、あなたが説明したことを正確に説明します.

Web サーバーが単一のプロセスを単一のスレッドで実行するように設定されていない限り、これは実際には「予期される動作」ではありません。これにより、Web サーバーが一度に 1 つの要求しか処理できない状況が発生し、ネットワーク上のすべての人に影響が及びます。これがまさに、Web サーバーがおそらくこのように設定されない理由です。実際、このようにサーバーを構成することは不可能であることがわかると思います。サーバーが役に立たなくなるからです。そして、賢いアレックが「Node.js はどうですか?」と言う前に。- これは特殊なケースです。すでによくご存じだと思います。

PHP スクリプトでセッションが開かれている場合、セッション データが保存されているファイルが排他ロックされます。これは、session_start()PHP がセッション データ ファイルの排他ロックを取得しようとしている間、後続のリクエストが への呼び出しでブロックされることを意味します。前のリクエストにはまだ排他ロックがあるため、取得できません。前のリクエストが完了するとすぐに、ファイルのロックが解除され、次のリクエストが完了できるようになります。セッションはマシンごと (実際にはブラウジングセッションごと、名前が示すように、別のブラウザーで動作する理由) であるため、ネットワークの他のユーザーには影響しませんが、サイトが設定されたままになるため、あなただけの問題は悪い習慣であり、簡単に回避できます。

session_write_close()これに対する解決策は、特定のスクリプトでセッション データの処理が終了したらすぐに呼び出すことです。これにより、スクリプトはセッション ファイルを閉じ、ロックを解除します。実行時間の長いプロセスを開始する前にセッション データを終了するか、プロセスsession_start()が完了するまで呼び出さないでください。

session_write_close()理論的には、スクリプトの後で呼び出してから再度呼び出すことができますがsession_start()、PHP はこの点でバグのある動作を示すことがあることがわかりました (これは Cookie に関連していると思いますが、それについては引用しないでください)。明らかに、Cookie を設定するとヘッダーが変更されることに注意してください。そのためsession_start()、データを出力する前、または出力バッファリングを有効にする前に呼び出す必要があります。

たとえば、次のスクリプトを考えてみましょう。

<?php

  session_start();

  if (!isset($_SESSION['someval'])) {
    $_SESSION['someval'] = 1;
  } else {
    $_SESSION['someval']++;
  }

  echo "someval is {$_SESSION['someval']}";

  sleep(10);

上記のスクリプトでは、2 番目のリクエストを行う前に 10 秒待つ必要があります。ただし、行session_write_close()の後に呼び出しを追加するとecho、前の要求が完了する前に別の要求を行うことができます。

于 2012-06-06T09:38:00.520 に答える
0

うーん...私はチェックしませんでしたが、Webサーバーへの各リクエストは独自のスレッドで処理されると思います. これにより、別のリクエストがブロックされないようにする必要があります。試してみてください :-) 別のブラウザーを使用して、大きなスクリプトの実行中にページにアクセスしてください。

Err ..これがあなたのために働いたことがわかります:-)そして、他の人にとってもそうです。

于 2012-06-06T09:28:11.717 に答える