質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Q&A

解決済

1回答

3081閲覧

ReactPHPを使った非同期処理のタイムアウト実装方法について

rokugasenpai

総合スコア8

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

0グッド

0クリップ

投稿2016/07/06 04:57

編集2016/07/06 11:23

###前提・実現したいこと
ReactPHPのevent-loopとpromiseを使って非同期処理のタイムアウトを実装したいです。
Webサーバはからまず、バッチ内のユーティリティメソッドで実装するつもりです。

###発生している問題・エラーメッセージ
$timeout_loop->addTimer(...);
$timeout_loop->run();
の順番に記述して実行すると、run()の次へ処理が進まず、addTimer()が完了するまで待ってしまう。
下記のソース1のvar_dumpを基準に言うと、現状ではA→B→C→F→Gとなり、
目的の処理であるD・Eを通らない。
問題解決のためaddPeriodicTimer()を使ったソース2を用意した。
非同期ならAAAA...BBBB...と出力されるはずだが、実際に実行すると、
A(1秒後)BA(1秒後)B...と非同期とは考えられない出力になった。
何か勘違いしてるはずなんだけど...

###ソース1

PHP

1<?php 2namespace Hoge; 3 4use React\EventLoop; 5use React\Promise; 6 7class Util 8{ 9 // タイムアウトつきでeval()の結果を返す。 10 public static function eval_with_timeout($code, $timeout_sec=10) 11 { 12 $result = FALSE; 13 $loop = EventLoop\Factory::create(); 14 $deferred = new Promise\Deferred(); 15var_dump('A:' . microtime(TRUE)); 16 17 // $timeout_sec秒を超えたらFALSEを返すことになる。 18 $timeout_loop = EventLoop\Factory::create(); 19 $timeout_loop->addTimer($timeout_sec, 20 function () use (&$deferred, &$loop) { 21var_dump('B:' . microtime(TRUE)); 22 $deferred->reject(); 23 $loop->stop(); 24var_dump('C:' . microtime(TRUE)); 25 }); 26 $timeout_loop->run(); 27 28 $promise = $deferred->promise()->then( 29 function () use ($code, &$result, &$timeout_loop) { 30var_dump('D:' . microtime(TRUE)); 31 $result = @eval($code); 32 if (is_null($result)) 33 { 34 $result = FALSE; 35 } 36 $timeout_loop->stop(); 37var_dump('E:' . microtime(TRUE)); 38 } 39 ); 40 $deferred->resolve(); 41 42var_dump('F:' . microtime(TRUE)); 43 $loop->run(); 44var_dump('G:' . microtime(TRUE)); 45 return $result; 46 } 47}

###ソース2

PHP

1$deferred = new Promise\Deferred(); 2$loop = EventLoop\Factory::create(); 3$timeout_sec = 0.1; 4$tick = 0.01; 5$elapsed = 0.0; 6$loop->addPeriodicTimer($tick, 7 function (EventLoop\Timer\Timer $timer) use ($loop, &$elapsed, $tick, $timeout_sec) { 8 $elapsed += $tick; 9 var_dump('A:' . microtime(TRUE) . ':' . $elapsed); 10 // 非同期ならAAAA...BBBB...と出力されるはず。 11 sleep(1); 12 var_dump('B:' . microtime(TRUE) . ':' . $elapsed); 13 if ($elapsed >= $timeout_sec) 14 { 15 $loop->cancelTimer($timer); 16 var_dump('C:' . microtime(TRUE)); 17 } 18}); 19$loop->run();

###お願い…
ReactPHPで使われる非同期処理については、
node.jsやCommonJSを扱ったことがないので基本的な理解が不足しているかもしれません。
JavaのAsyncTask、C#のTaskなら扱ったことがあります。
ReactPHPにこだわっているわけではないので、
他に分かりやすく目的を満たせるようなライブラリがあればそちらを使いたいです。

###補足情報(言語/FW/ツール等のバージョンなど)
PHP5.4 / ReactPHP最新版 / Windows

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

自分のやろうとしていたことはできないみたいです。
ノンブロッキングI/O≒マルチスレッドと勘違いしてました。
https://github.com/reactphp/react/wiki/FAQ
https://blog.wyrihaximus.net/2015/01/reactphp-timers/
↑Blockingの項目

投稿2016/07/07 17:24

rokugasenpai

総合スコア8

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問