1 名前:デフォルトの名無しさん mailto:sage [2016/05/11(水) 21:46:50.27 ID:e/4BOK4y.net] PHPに関する下らない質問用避難スレです。 まず読むこと【PHPマニュアル】 www.php.net/manual/ja/ 前スレ 【PHP】下らねぇ質問はここに書き込みやがれ 4 [無断転載禁止]©2ch.net echo.2ch.net/test/read.cgi/tech/1457792733/ 次スレは>>980 が立てる。10分以内に立たない場合、宣言してから立てたい人が立てること。
684 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 13:30:10.44 ID:vIdecit0.net] なんでもは言いすぎだったな。 でもいろんな応用をするための基礎だからやっとけって。
685 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 13:36:56.47 ID:U0YLx5iK.net] >>680 「なんでも排他できるだろ」っておまえはアホかぬ? 排他する事だけがシステムの目的みたいになってるアホ発言だぬー そんなにはいたいなら医者行けばいいぬー ファイルで取り回すよりDB使ったほうがやれることがはるかに膨大なんだぬー 排他なんてそのうちのほんの1メリットだぬー だったらDB使っちゃったほうがお得だぬー とか言ってると、「DB使えない場合はどうすんだ」とか言うアホがでてくるんだぬー だから今のうちに言っとくぬー 一般的でないケースの事なんか知るかハゲ!
686 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 13:38:31.55 ID:U0YLx5iK.net] >基礎だからやっとけって。 DBは今時常識だからやっとけって。
687 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 13:41:00.34 ID:c3/xDSGs.net] >>668 if (flock($lock, LOCK_EX)) { ... } という風に失敗した場合の分岐を用意しよう また新しいPHP(5.3.2以降)では手動でflock($lock, LOCK_UN)する必要があるらしい
688 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 13:42:44.74 ID:vIdecit0.net] >>683 DB 使うなとは言ってないぞ。 手持ちのカードが多ければ好きに使い分けられるだろ。 お前はアクセスカウンター作るにもDB使うんだろうが、その選択しかできないのであれば潰しがきかないぞ。
689 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 13:43:06.58 ID:U0YLx5iK.net] ほら、なんかいろいろとめんどくさい情報がくっついてきたぬー おまえら、人生楽しそうだぬー
690 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 13:45:16.50 ID:U0YLx5iK.net] >>685 ファイル操作にこだわってるお前のほうが潰しきかないから他人の心配してる暇ないんじゃないかぬー?
691 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 13:46:22.53 ID:vIdecit0.net] >>684 LOCK_UN 必須の件は初耳だったけど、それ本当? この辺の機能は OS の機能をそのまま使ってて、そんなに差がでる部分じゃないというか、ハンドル閉じてロックだけ残るってどういう事情だよって感じだが。 ハンドルを複製してるケースとかかな?
692 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 13:49:14.38 ID:U0YLx5iK.net] >>688 おまえが調べてQiitaにでもまとめといてくれぬ。 必要になった時に見てやるぬ。 それまでは俺様は優雅にDB使ってるぬ。
693 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 13:53:03.18 ID:vIdecit0.net] >>684 5.3.3 で試したけど、少なくとも >>668 の使い方では LOCK_UN の明示は要らないね。
694 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 13:55:02.40 ID:c3/xDSGs.net] >>688 ついさっき確認したら変更履歴にそう書いてあったからであって、俺は検証してないよ php.net/manual/ja/function.flock.php どうなるのか想像でしかないが、解放しないと2度目からFALSE返すとかじゃね
695 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 13:57:05.92 ID:U0YLx5iK.net] 圧倒的な人柱感
696 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 13:58:16.03 ID:U0YLx5iK.net] そういう、ファイルシステムの影響モロに受けそうな処理を平気でやる人たちって、 結局心が強いんだろうな。 オレはチキンだから無理だぬー
697 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 14:18:34.99 ID:a1oB3JFl.net] まーた馬鹿が暴れてるのかー
698 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 14:24:21.01 ID:U0YLx5iK.net] まーた馬鹿が戯言だけホザくのかー
699 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 14:29:21.37 ID:U0YLx5iK.net] 本当に、まともな思考力のある人間はいないのかねぇ…
700 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 14:39:42.63 ID:a1oB3JFl.net] え?自分がまともな思考力もってると思ってんの?
701 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 14:46:49.83 ID:7IE41uX0.net] >>668 ロック用ファイルを別に用意するんですね ありがとうございます ちなみにやたらdbを推してる狂人がいますが 今書いてるのはなるべく他のプログラムを使いたくないものなので、 今のところdbは考えていません
702 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 14:54:08.42 ID:U0YLx5iK.net] >>697 自己紹介乙 このスレの参加者は自己紹介だけは得意だ
703 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 14:55:15.54 ID:U0YLx5iK.net] >>698 なんか修行でもしてるんだ。学生は暇でいいね。
704 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 14:57:12.43 ID:U0YLx5iK.net] PHPerはとにかく何でもPHPでやりたがるというのは本当だな。 脳みそが崩壊してる。
705 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 15:36:01.25 ID:a1oB3JFl.net] ノウミソ崩壊って自己紹介はやめろって!
706 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 15:43:02.88 ID:U0YLx5iK.net] オウムさん餌でもついばんででください
707 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 15:45:49.48 ID:U0YLx5iK.net] 人間、いないねぇ…
708 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 15:59:10.40 ID:a1oB3JFl.net] 低収入オッサンやめろよ ここはストレス発散のはけ口じゃないんだよ!!!
709 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 16:05:51.89 ID:U0YLx5iK.net] うん、ここはお前らの低能をなぐさめあう場所でもない。わかってるだろ?
710 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 16:06:40.12 ID:U0YLx5iK.net] あと、さすがに酔いがまわってきたから突然落ちるよ。
711 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 16:08:50.21 ID:a1oB3JFl.net] 低能低能いうけどお前レベル低いからな(笑)自覚しろよ!!!
712 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 16:11:06.58 ID:ZgIjL8Zc.net] 最初flock絡みでデッドロックやらかした時は スクリプト止まらないしエラー吐かないしで何が悪いのか全然わからなくて立ち往生状態だった >>698 serializeほど楽じゃないが別途db用デーモンを起動させとかなくていいsqliteは便利 そういや手軽なdbの話じゃ最近berkeley dbの名前を全然見ないな…なんでだ
713 名前:デフォルトの名無しさん [2016/06/11(土) 16:11:26.13 ID:BbMy6dfc.net] PHP使ってるのなんてみんな底辺だから仲良くしようや
714 名前:668 mailto:sage [2016/06/11(土) 16:16:02.35 ID:0LrYNLoc.net] >>698 >>684 の情報により、fclose の前に flock($lock, LOCK_UN) を入れてね。 あと flock 使った排他で重要なところは、処理が終わってもロックファイルを消しちゃダメということ。 ロックファイルの存在確認式なんかだと処理が終わったらロックファイルを消す必要があるけど、flock式はそうじゃない。 同一のファイル(パスではなく inode)をオープンすることでロックをかけるから、消して作り直しても同じファイルにはならずその間でのロックがかからない。 あと、NFS 領域に対しては flock が使えない場合があるから、それは制限事項として覚えておいて。 といった具合に説明すると長くなるけど、コードはシンプルだから覚えておいて損は無いよ。
715 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 16:24:29.25 ID:ZgIjL8Zc.net] >>691 いや違う、falseを返すとかじゃなくてデッドロックを引き起こす 延々とロック取得待ち状態になってkillしなきゃいけなくなる
716 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 19:09:00.14 ID:U0YLx5iK.net] お前ら、人生楽しそうだな。 俺は頭痛い…
717 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 19:12:41.27 ID:U0YLx5iK.net] おっかしいな… なんでこんなに頭いたいんだ?
718 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 21:39:16.03 ID:vIdecit0.net] >>712 マニュアルに書いてあることにケチつける気は全く無いんだけど、 Linux の 5.3.3 と Windows7 の 5.6.22 で実験しても、LOCK_UN が必要だと思われる挙動が認められない。 fclose だけでロックは外れるし、同プロセス内で同じハンドルに対してアンロックも fclose もしないまま 2重にロックを掛けてもデッドロックしない。 どういうケースで LOCK_UN の明示が必要なんだろう? 実験コードはこれ。 $lock = fopen('lock','a'); echo "start\n"; if(!flock($lock, LOCK_EX)) { echo "fail 1\n"; exit(1); } echo "locked 1\n"; // ロック成功 if(!flock($lock, LOCK_EX)) { echo "fail 2\n"; exit(1); } echo "locked 2\n"; // 二重ロックでもデッドロックしていない fgets(STDIN); // ENTER が押されるまで待つ fclose($lock); // アンロックせずクローズ print "unlocked\n"; sleep(5); // プロセスの終了を引き延ばす(ロック残り状態があるならそれを維持する) print "end\n";
719 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 22:15:24.50 ID:ZgIjL8Zc.net] >>715 すまんが712は単純に「LOCK_EXされたファイルへのLOCK_EX」の挙動を書いただけ flockの仕様から同一プロセスからの多重flockは後に指定したLOCK_**に上書きされるだけ、なのも確実(winは知らん) で、記憶掘り返しながらこっちでも試してみたけど>>715 の言うとおり 同一プロセス内でも、別プロセスでも、fopen->flock->fclose->fopen->flock でデッドロックしなかった flock($fh, LOCK_EX)絡みでデッドロックになってハマった記憶が確かにあるんだがなあ…しかも1プロセスで 昔書いたソースとメモを読んでるけど該当箇所が見つからん
720 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 22:25:33.55 ID:U0YLx5iK.net] 具合悪い… 吐きそう…
721 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 22:43:11.56 ID:vIdecit0.net] >>716 アンロックも fclose もせずに fopen からやり直したに一票。 $lock = fopen('lock','a'); flock($lock, LOCK_EX); echo "locked 1\n"; $lock = fopen('lock','a'); flock($lock, LOCK_EX); echo "locked 2\n"; それは置いといて、仕様変更の事情が気になったので PHP のソースを読み始めた。 読んで分かるかは分からんけど、とりあえずソースを flock で grep したところから辿ってる。
722 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 22:53:40.15 ID:U0YLx5iK.net] 排他的に内容更新したいだけなのにお前ら何やってんだよ…
723 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 23:21:54.93 ID:u5pRtWh9.net] 僕の友達に「ゲームプログラムを兄から頼まれてよくやってるー」などと言ってる奴がいます。そいつにどんな言語使ってんの?とかきいてもいろんな言語使ってるから意識したことないわwとか誤魔化したり、c言語は難しくてよくわからんとか言っているのです。 なんか嘘くさいんで掘り下げてやろうと考えてます。 もしゲームプログラムするならこれは知ってて当然みたいな知識あったらそいつに仕掛けて反応見てみたいので教えてください。
724 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 23:27:06.01 ID:u5pRtWh9.net] 各場所間違えてました ごめんなさい
725 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 23:36:10.98 ID:ZgIjL8Zc.net] >>718 そんな感じがしてきた。(だが718のコードだと$lockを上書きしちゃってるからデッドロックは起きない) 同一のファイルを二重に開いて別々にファイルハンドルを保持し別々にflockしたとき 片方だけでもfcloseしたら両方LOCK_UNされることの対策か、とも思ったけど 実際に下記を手元のwin-5.2.0とlinux-5.1.6とlinux-5.6.8で試してみたら、どうも違うようだ $file = './flock.lock'; $fh1 = fopen($file, 'a'); flock($fh1, LOCK_SH); $fh2 = fopen($file, 'a'); flock($fh2, LOCK_SH); fclose($fh1); $fh3 = fopen($file, 'a'); flock($fh3, LOCK_EX); // いずれもここでデッドロックが発生 わからん
726 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 23:46:33.60 ID:vIdecit0.net] >>722 上書きしてるから起こるんだよ、オブジェクトみたいに変数上書きしたら参照が無くなった方が勝手に破棄されるんじゃないから。 でも本質は、一つのハンドルには何度繰り返しロックをしてもスルーされるけど、一つのファイルでも別個の 2つのハンドルを取得しちゃった場合、 その両方にロックを掛けたらそりゃ 2度目の方はブロックされるという点。 意図せずこのバグを引き起こすケースとしてはこんな感じじゃね。 $lock = fopen('lock','a'); flock($lock, LOCK_EX); <なんかの処理、でもうっかり $lock の値を壊してしまう> fclose($lock); // ロックを解放したつもりだけど、$lock が正しいハンドルを示していないから失敗、ハンドルリーク $lock = fopen('lock','a'); flock($lock, LOCK_EX); // 二度目のロック、同じファイルだけどさっきのロック取得済みのハンドルとは別ハンドルになるからロックを取得できない :
727 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 23:50:10.54 ID:vIdecit0.net] >>723 ごめんうそ言った。 ハンドルを上書きしたらクローズされてるみたいね? なので >>723 は忘れて。
728 名前:デフォルトの名無しさん mailto:sage [2016/06/11(土) 23:57:31.23 ID:ZgIjL8Zc.net] >>724 気にすんな しかしこうなると真面目に手動LOCK_UNの意味・有効な場面がわからなくなってくるな というかfclose/flock仕様変更の前後の差異がわからん
729 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 04:10:30.87 ID:p2hTIoUv.net] 懐かしい話を掘り起こしているようで tumblr.tokumaru.org/post/37141017115/
730 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 04:35:52.53 ID:jxNAYoxL.net] オブジェクト指向はアクセス指定子や抽象クラスなどで やってはいけないことや守るべきことをコードの中で示すことができますが フォークすることによって起きる事態に対しては無力だと思います たとえば、プロセスidを入れ込んだファイルパスは、 その都度getmypidを呼んで生成しなければいけない、 というようなことを、コードのシンタックスによって示すことは出来ませんよね コードのどこかでフォークしているということに気付かずに いちいち毎回作り直さずにキャッシュすればいい、と思うことはありそうです いい方法はないでしょうか?
731 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 07:55:29.22 ID:4xmbllsr.net] >>726 参考になった。ありがとう。 でもこれ、system関数のバグなんじゃね? 内部で fork した後、親プロセスから継承したハンドルを閉じてないんじゃ? そこのデッドロックのサンプルだと、デッドロック中はロックファイルの lsof は子プロセス側に 2件ある。 5.3.2 での改修ポイントが間違ってたんじゃないのかなぁ… 少なくとも OS のシステムコールレベルではハンドルを閉じればロックも否応なく外れちゃうし、これは Unix系も Windows も一緒なはずだが。
732 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 08:18:59.24 ID:4xmbllsr.net] 検証した。 やっぱ子プロセスが継承したハンドル持ちっぱなしだよ。 当然マルチプロセスの処理を書く時にはそれを意図的に利用したいことはあるけど、PHP だったら内部で exec系を行う前にはスクリプトで開いたハンドルは全部クローズするべきなんじゃないのかね。 ただ現象が起こる理由は分かったから、それに基づけば明示的なアンロックが無くても影響があるところはほとんど無さそうだと判断するけどな。
733 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 13:06:26.58 ID:0JopogCG.net] そもそもflockシステムコールはもともとマニュアルに書いてあるように flock() によって作られるロックは、 オープンファイル記述 (open file description) (open(2) 参照) と 関連付けられる。 したがって、ファイルディスクリプターの複製 (fork(2) や dup(2) などにより作成 される) は同じロックを参照し、 これらのファイルディスクリプターのどれを使っても このロックを 変更したり解放したりできる。 また、ロックの解放は、 上記の複数のファイルディスクリプターの いずれかに対して 明示的に LOCK_UN 操作を指示した場合か、これらのファイルディスクリプターが すべて 閉じられた場合に行われる というもので、phpのfclose関数の中でわざわざLOCK_UNしてたのは余計なお世話 で本来の動作を阻害していたから5.3.2でやめたって理解でいいんだろうか。
734 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 13:26:47.31 ID:4xmbllsr.net] >>730 うん、よくよく考えると > というもので、phpのfclose関数の中でわざわざLOCK_UNしてたのは余計なお世話 ということが正しいと思う。 元々マルチプロセスなプログラミングで自動で複製されるファイルディスクリプタの扱いはプログラマが意識する必要があって、複製の後始末をせずにロックが残ることがあるのはそもそも設計ミス。 こういうことをフォローするために PHP では fclose でのついでに自動でアンロックが走るようにしていたけど、そうると親子プロセスの一方で不要になったディスクリプタを閉じただけでロックまで外れちゃうという問題を引き起こす。 だったらリソースの管理はやっぱりプログラマに任せるって判断が妥当なんだろう。 互換性の点でも、そもそもディスクリプタの複製が行われるケース(恐らく PHP では fork を伴う何か)と関係無ければ fclose だけでロックは解放されるから問題は無いし、 複製が行われるような処理ではアンロックの必要性についてはプログラマが意識していてしかるべきだから、 結局のところ fclose にアンロックを合わせこむのをやめるのが正解だな。 ただ system をはじめとするシェル系の関数は気軽に使いがちだから、子プロセスのハングアップでロック残りが起こる可能性は身近かもしれないね。 これまでアンロックせず動いてたスクリプトを無理やり改修する必要までは無いけど、これから書くならアンロックは明示しとけってことだな。 久々に勉強になった。
735 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 14:20:54.54 ID:QWuFqOwW.net] >久々に勉強になった。 使う機会あるといいけどな。
736 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 14:39:38.95 ID:Y/PMYUAu.net] 別に子プロがハングしようとLOCK_UNには関係ないんじゃないか execしたphp以外のプロセスがロックしててもphpのロックには関係ないし どんなプロセスでもプロセスが終わればロック解放されるんだから
737 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 15:10:09.70 ID:3j0TR14y.net] >>733 ハングして終了しなければ殺すまでロックしっぱなしだろ
738 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 15:21:03.49 ID:3j0TR14y.net] 説明が足りないか。 PHPでファイルを開きロックをした状態で、例えば system で別プロセスを起動したとする。 このプロセスは、PHP で開いていたファイルディスクリプタの複製を持つ。 ディスクリプタが複製されても取得しているロックはひとつで、このディスクリプタのいずれかでアンロックすればロックは解放される。 誰もアンロックしなかった場合、そのロックに紐付く全てのディスクリプタが閉じられた場合に解放する。 つまりディスクリプタの複製を持った子プロセスがそれを閉じないままハングした場合、親プロセスがディスクリプタを閉じてもロックは解放されず、子プロセスを殺すまでロックされたままになる。 ちなみに子プロセスがPHPかどうかは関係無い。
739 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 15:29:21.61 ID:jxNAYoxL.net] ファイルパスを正規化するにはどうすればいいですか? realpathで出来ると思っていたのですが まだファイルが存在しない時点では結果がfalseになるので駄目でした
740 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 16:09:50.68 ID:hcrF9o1u.net] >>736 標準関数にはない。 Packagistには恐らくあるだろう。
741 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 17:23:27.51 ID:jxNAYoxL.net] >>737 ありがとうございます packagistというところから辿ったらありました https://github.com/perchten/php-truepath/blob/master/src/truepath.php
742 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 17:28:53.54 ID:pWHiM9s7.net] とりあえず話が収束したらまとめとして残してくれる? ここまで議論しといて残さなかったらPHPerとして恥だし
743 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 17:51:52.67 ID:SdG9GRKe.net] 他力本願こそPHPerとして恥だぞ
744 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 18:52:27.13 ID:Y/PMYUAu.net] >>734-735 あるファイルをphpで有効にLOCK_EXしても別プロセスで起動したviには何も影響しないと認識していたが? だからphp以外をexecしてロックが生じてもphpの記述には関係がない=fclose前のLOCK_UNに関係ない ある.php内であるいはexecで呼び出した.phpでファイルロックが起きてもmax_execution_timeの縛りで強制終了すればロックは解ける ゆえに「ロック残り」とやらで掴みっぱなしになることはそうそうない、そう認識していたんだが
745 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 18:52:38.31 ID:QKWa7och.net] で、お前らぴーえいちぱーって読んでんの?
746 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 19:03:36.38 ID:4xmbllsr.net] >>741 flock によるロックって別のプロセスからのファイルアクセスを禁止するわけじゃないから。 同時にロックを取得できないだけであり、それによって「ロックを取得しようとするプロセス同士」を排他するわけ。 ロックを取得しようとしないプロセスはロックされたファイルであろうとアクセスし放題だよ、例えば vi とかね。 Windows では他のプロセスからのファイルアクセスを禁止することもできるけどな。
747 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 19:06:30.53 ID:QKWa7och.net] ピーチクパーチク、ピーエイチパーチク ヨー、チェケラッチョー
748 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 19:15:10.09 ID:Y/PMYUAu.net] >>743 あれviってflock使ってなかったっけ?まあいいや他のなんでもいいんだが 本旨はphpにおける明示的flock($lock,LOCK_UN)の必要性だろう、それが他プロセスとどう関わるんだ 結局どういうときにLOCK_UNしないと「ロック残り」が起こるんだ
749 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 19:35:01.71 ID:4xmbllsr.net] >>745 >>726 の実験コードで再現できるよ。 デッドロックのメカニズムはこう。 まず a.php でファイルを開き、ロックする。 そして system で b.php を開く(別に PHP である必要は無い)。 この段階で b.php は、a.php が開いていたファイルの fd(ファイルディスクリプタ)の複製を継承する。 b.php は継承した fd とは別に自前でファイルを開き、ロックしようとする。 ロック済みのファイルに対してロックしようとするから、これはブロックする。 この間 a.php は処理が進み、fclose が走る(*1)。 プログラマーの意図としてはここでロックも自動的に解放されると思っているが、このロックを共有する fd を b.php が閉じずに持っているので、まだロックは解放されない。 a.php は終了するがロックは解放されないので、b.php のブロックが解けることも無くデッドロックする。 このスクリプトをデッドロックさせずに走らせるためには、*1 の前に LOCK_UN するのが一案(PHP においては唯一の手段)。 これにより b.php は継承した fd を開かれたまま持ってはいるが(ある種のリソースリーク状態)、ロックは a.php により解放されるので、b.php が自分で開いた fd に対するロックを取得でき、処理が進行する。 もう一案は、PHP では実現不能だと思うけど、b.php が走り出した直後に継承した fd を閉じること。 PHP からは継承した fd の存在が見えないし、fd を知ることができたところで何もできないから詰むけど、fd を操作できる処理系ではそれが可能だし、むしろ常套手段。 ようは、何かのファイルをロックしたまま子プロセスを立ち上げ、その子プロセスが同じファイルのロックを取得しようとするかなり限定されたケースでは LOCK_UN が必要。
750 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 19:43:46.46 ID:4xmbllsr.net] ついでにもう少し、>>746 のようなケースであれば、5.3.2 よりも前のように flose で LOCK_UN してくれりゃいいじゃんと思うかもしれない。 多分 PHP の設計者もそう思って、そうしていたんだろう。 でも pcntl_fork なんてことができるようになると、それじゃ問題が出るケースにぶち当たる。 通常 fork してもやっぱり親が持っていた fd は子プロセスに継承されるし、pcntl_fork に関して言えば継承された fd はファイルハンドルの形で PHP から操作できる状態で見えている。 通常マルチプロセスの処理は、親が持っていた fd はじめいろいろなものを継承してしまうので、子にとって不要なものを閉じてしまうというのが最初にやること。 親がロックを取得した fd をそのまま親と子で共有するなんてことはめったに無いから、親なり子なりでその fd を閉じる処理を書くことになる。 この時 LOCK_UN が自動的に走るようになっていると、そのロックを必要としている方のプロセスが持つロックまで解放され、非常に具合が悪い。 だから fclose で勝手に LOCK_UN するなんてのは余計なお世話以外の何物でもない。 というわけで、fclose で LOCK_UN しないようになったと、こういうことだよ。
751 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 19:49:34.59 ID:4xmbllsr.net] >>747 > 親がロックを取得した fd をそのまま親と子で共有するなんてことはめったに無いから、親なり子なりでその fd を閉じる処理を書くことになる。 ちょっと誤解を招くかもしれないから捕捉。 親がロックを取得した fd をそのまま親と子で共有するなんてことはめったに無いから、 その fd はどちらか一方にとっては不要であるから、そちらのプロセスでは最初にその fd を閉じる処理を書く。
752 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 19:58:20.79 ID:p2hTIoUv.net] >>745 プロセスが生きている間においては「ロック残り」が発生するが、どうせ死ぬから問題ないというスタンスだとすれば、 max_execution_timeを0にした場合や、(初期値が0である)CLIの場合は生き続けるよ。
753 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 20:37:09.64 ID:SRdEl8UG.net] HTMLとは ハイパー テキストマークアップ ラングアゲ
754 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 21:40:22.72 ID:ETS5lku+.net] ランゲージ
755 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 09:32:27.21 ID:Mgx0zrpD.net] 今phpをステップ実行できるデバッガで便利なのってどのあたり? ステップごとにそれぞれの変数の中身がどうなってるか簡単にわかるとうれしい
756 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 13:49:19.06 ID:XIduanRK.net] array_filterで関数に他の引数も与えたい場合はどうしたらいいですか?
757 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 14:23:37.32 ID:TYgkMCrQ.net] >>753 コールバックにオブジェクトメソッドを指定して、オブジェクトに他のパラメータを持たせるとか?
758 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 14:36:57.48 ID:TYgkMCrQ.net] あんまやったことないけど、クロージャでやる方が簡単なのかね? function my_array_filter(array $input, $param) { return array_filter( $input, function($var) use($param) { return $var <= $param; } ); } $a=array(1,2,3,4,5); print_r(my_array_filter($a, 2)); print_r(my_array_filter($a, 4)); <実行結果> Array ( [0] => 1 [1] => 2 ) Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 )
759 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 15:15:41.61 ID:XIduanRK.net] >>755 phpもクロージャ出来るようになってたんですね ありがとうございます
760 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 16:04:29.44 ID:poUAr+t+.net] Array→アレイ→アレ?→あれれ? という発想が頭から離れなくて頭が基地外になりそうなんだけどプログラミングは向いてないよね? ちなみに仕事はPG全く関係なくて異業種の作業員
761 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 18:18:38.79 ID:Mj2HqjrQ.net] おでかけですか〜?
762 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 18:53:18.04 ID:I48wzFwG.net] おまえら、平和でいいな。
763 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 00:37:10.95 ID:e/1BDrQk.net] >>757 電気屋さんとか電波屋さんと仲良くなれそう
764 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 02:04:02.36 ID:vpCPShaK.net] 配列をオブジェクト指向的に使うための組み込みクラスは何故ないのでしょうか?
765 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 03:26:27.75 ID:E92ohJVI.net] ないんですか?
766 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 03:29:28.98 ID:sdXnBDtj.net] >>761 当初はあまりオブジェクト指向じゃなかったという点と、 現状の array をそのままオブジェクトとして見なす変更をしてしまうと array を関数の引数に取る場合に他のオブジェクトの扱い(array はコピー渡し、オブジェクトは参照渡し)と一貫性が取れなくなるから、今更どうにもできないってところじゃね。 それより、関数が返す array を直接添え字でアクセスできないのをなんとかして欲しい。 ようは explode(',', $str)[1] みたいにやりたいわけだが、この改修ならほとんど問題無くできそうな気がするけどな。
767 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 03:34:56.83 ID:pjhL6UK+.net] list(,$test)=explode(',', 'test1,test2,test3'); こうするのがせいぜいだが、これで妥協するか自分自身が開発に参加して改修するかだな
768 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 03:48:41.99 ID:E92ohJVI.net] できないんですか?
769 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 05:18:59.07 ID:jLlAbvBE.net] ArrayObjectとArrayIteratorならあるぞ
770 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 09:39:15.99 ID:1o9WExv+.net] >>761 実装済みの>>766 に加えて自前クラスでもArrayAccessインターフェイスを実装すれば配列のように扱えるクラスを実装出来る
771 名前:デフォルトの名無しさん mailto:sega [2016/06/14(火) 10:25:21.42 ID:ekIyBZy6.net] PHPStorm を優勝期限切れで使い続けてる人います? バージョンアップできなくてつらくない?
772 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 11:58:51.69 ID:vpCPShaK.net] ありがとうございます ArrayObjectってあったんですね 探し方が足りなかったようです やはり関数言語的な書き方をしようと思うと、生配列だと物足りなくなってきますね ただArrayObjectも、関数言語的なメソッドは実装されてないようです eachやmapやreduceなど 既にそういうの書いてる人はいるでしょうけど、 標準実装してほしいところです
773 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 12:23:57.32 ID:nAMCA7y/.net] >>763 explode(',', $str)[1] については いつまでも古いバージョンのPHPつかってんじゃねーよってことだが。
774 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 17:44:21.80 ID:vpCPShaK.net] class ArrayObjectEx extends ArrayObject { public function map($func){ foreach ($this as $key => $value){ $this[$key] = $func($value,$key); } return $this; } } とりあえずmapを作ろうと上みたいな感じにしたのですが インスタンスのmapを呼び出すとundefined functionと言われます 親クラスにないメソッドを追加することは出来ないのでしょうか? だとしたらそんな制限は意味が不明すぎますが・・
775 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 19:05:12.07 ID:4d00OzM8.net] 検証すんのめんどくさいから全部コード乗っけてくれる?ハゲ
776 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 19:26:39.01 ID:E92ohJVI.net] mapに何を渡したんですか?
777 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 21:39:45.32 ID:vpCPShaK.net] 失礼しました あまりの非PHPっぽさに釣られて $a.hoge(); みたいな書き方をしていました
778 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 23:57:10.36 ID:sdXnBDtj.net] >>770 あれ本当だ いつの間にこうなった
779 名前:デフォルトの名無しさん mailto:sage [2016/06/15(水) 00:30:10.47 ID:yBESscco.net] >>775 5.4からだから既に4年以上前
780 名前:デフォルトの名無しさん mailto:sage [2016/06/15(水) 01:15:30.82 ID:/9sc4puR.net] explodeの戻り値がfalseだったら文字列でもfalseでもない null が返ってくることになるよな、それ noticeも出る
781 名前:デフォルトの名無しさん mailto:sage [2016/06/15(水) 02:58:03.10 ID:6YnDO2OY.net] そうですね
782 名前:デフォルトの名無しさん mailto:sage [2016/06/15(水) 09:56:12.92 ID:35n6X8km.net] >>776 ずっとそれ出来ないもんだと思ってた...
783 名前:デフォルトの名無しさん mailto:sage [2016/06/15(水) 10:18:18.00 ID:HJSiSv4s.net] 猿は勉強しないから知らなくても無理はない。気にすんな。
784 名前:デフォルトの名無しさん mailto:sage [2016/06/15(水) 11:45:48.59 ID:DNtAqMfa.net] わかった。 もう気にしない。