暴言満載

ネット上でぐらい暴言吐かせて・・・

NHKの論理は崩壊している

2007-05-16 22:31:17 | 未分類
NHKが未契約者の訴訟準備 事業所に締結求める文書 産経新聞
受信契約については、憲法の「契約自由の原則」に反するとの指摘もあるが、NHKでは「テレビを買う買わないは視聴者の自由であり、あえてテレビを買ったという点で契約の自由には抵触しないと考えている」としている。

NHKはわざわざ矛盾を晒している。パナソニックやシャープやソニーが売っているのはNHK受信機ではなくテレビだ。
放送法の規定は憲法違反だという立場に立つと、テレビの購入は単純に電器屋さんとの契約で、テレビ局が介在する余地はない。だから契約自由の原則に違反しているという指摘に対して、「テレビを買わない自由」を持ち出しても意味を成さない。
コメント (8) |  トラックバック (0) | 

@ITのPHPの記事が突っ込みどころ満載

2007-03-10 00:45:22 | PHP
サンプルで理解! フォームデータの受け渡し
1ページ目
menu.phpは、排他処理を扱ったようですが、早速ひどいです。
「一般的なオンラインシステムでは同時処理に対するデータの矛盾が発生しないよう留意する必要があります。」と書いているので、単にファイルが壊れなければいいという考えではないみたいなのに。

(1)flockするまえにデータを読むな
(2)file_existsのあとでwモードでファイルを開くな
(3)set_file_bufferはOSのバッファリングは関係ない
(4)fcloseの前にflock解除するな

(1)について。ファイルにはあらかじめ 1000000004 と書いてあるとします。
ユーザー1が4行目でファイルを開く

ユーザー1が5行目で $order_no に 1000000005 を代入

ユーザー2が4行目でファイルを開く

ユーザー2が5行目で $order_no に 1000000005 を代入

ということで、ユーザー1とユーザー2の $order_no が一緒になってしまいました。

(1)を改善するとコードはこうなりますかね
$count_file="/tmp/count.dat";
if(file_exists($count_file)){
$file = fopen($count_file, "r+") or die("ファイルをオープンできませんでした");
set_file_buffer($file, 0);
flock($file, LOCK_EX);
$order_no = fgets($file) + 1;
}else{
$file = fopen($count_file, "w") or die("ファイルをオープンできませんでした");
flock($file, LOCK_EX);
$order_no = 1000000001;
}
rewind($file);
fputs($file, $order_no);
flock($file, LOCK_UN);
fclose($file);


(2)について。
file_exists と fopen の間はあいています。あいているということは、他のユーザーが割り込む可能性があるということです。
ユーザー1がfile_existsを調べる→ない

ユーザー2がfile_existsを調べる→ない

ユーザー1がfopen($count_file, "w")でファイルを開く(作成する)

ユーザー2がfopen($count_file, "w")でファイルを開く

ユーザー1の $order_no に1000000001を代入

ユーザー2の $order_no に1000000001を代入

file_existsで調べても、その直後に状況は変わってるかもしれないということです。改善策はいくつかあります。
その1
$count_file="/tmp/count.dat";
touch($count_file);
$file = fopen($count_file, "r+") or die("ファイルをオープンできませんでした");
set_file_buffer($file, 0);
flock($file, LOCK_EX);
$order_no = fgets($file);
if(empty($order_no)) $order_no = 1000000001;
else $order_no++;
rewind($file);
fputs($file, $order_no);
flock($file, LOCK_UN);
fclose($file);

その2
$count_file="/tmp/count.dat";
$file = fopen($count_file, "a+") or die("ファイルをオープンできませんでした");
set_file_buffer($file, 0);
flock($file, LOCK_EX);
$order_no = fgets($file);
if(empty($order_no)) $order_no = 1000000001;
else $order_no++;
ftruncate($file, 0);
fputs($file, $order_no);
flock($file, LOCK_UN);
fclose($file);


(3)について
「set_file_buffer("ファイルポインタ", 0)」で書き込みバッファを使用しないようにします。書き込みバッファはOSがメモリ上に用意する一時的な記憶領域です。ハードディスクなど物理的なファイルシステムに書き出す前に利用されます。
バッファを利用することで、書き込みパフォーマンスを上げることができる一方、極めて短時間ですが、バッファ上のデータとファイルシステム上のデータに差異が発生します。その差異が発生している瞬間に障害が起きた場合、データが消失する可能性があります。そのため、バッファを利用せずに直接ファイルシステムに書き込むようにします。

と書いてますが、set_file_bufferはOSのバッファではなくPHPの内部のバッファーを制御します。マニュアルを見れば分かることなのに。「その差異が発生している瞬間に障害が起きた場合、データが消失する可能性があります。」とのことですが、差異が発生していないときに障害が起こってもデータは消失するわけで(「障害」ってのが具体的になんなのかさっぱりわかりませんが)。
ようするに、set_file_bufferは不要です。ただし、(4)を守るなら。

(4)について。
fcloseの前にflock(ファイルポインタ, LOCK_UN) する人は実に多いのですが、これははっきりと間違いだと断言します。flockをfcloseの前に解除するということは、fcloseの前に他のプロセスが割り込む可能性が出るということです。ファイルへの書き込みは、fwriteとかfputsとかしてからfflushまたはfclose実行までのどこかで行われる、というのがファイル周りのI/Oの基本です。なので、fcloseもロックの範囲内に入れなければなりません。fcloseでflockが解除されるのはそういう理由があるのです。単に「ファイルが閉じられたらflockもなにもないだろう」ではないのです。ちなみに、バッファを無効にしてこの問題を回避と言うのは俺に言わせれば邪道です。

さて、2ページ目にはファイルの排他処理なんてレベルじゃない重大な問題があります。それも書こうかと思いましたが、今日は疲れたのでこの辺にします。

コメント (1) |  トラックバック (0) | 

思想の自由なんて詭弁にだまされてはいけない

2007-02-22 12:12:40 | 未分類
職務命令、強制やめて 君が代訴訟で原告団都教委に申し入れ (東京新聞)
●君が代伴奏拒否の教諭、敗訴確定へ=最高裁 (時事通信出版局)
この人たちも飽きないですね。憲法違反とか持ち出せばそれだけで相手のイメージダウンを図れる。「思想強制された」というだけで先入観で有利に立てる。
しかし、ちょっと冷静に考えて欲しい。

「社歌が嫌いだから社の行事には一切出席しません。」
「会社のシンボルマークが嫌いだから名刺には印刷しません。」
「私はあるタンカーの船長だが、日の丸は嫌いなので船には掲げません。」

思想の自由を持ち出すのは詭弁に過ぎない。騙されるな。
コメント (1) |  トラックバック (0) | 

--enable-maintainer-zts???

2007-02-20 10:27:20 | PHP
--enable-maintainer-zts オプションは、サーバー側がマルチスレッド動作かどうか関係なく強制的に Zend Thread Safety (ZTS) を有効にするオプションである。
これが必要な場面と言うのは、PHP本体の開発者やPHPのモジュールの開発者がZTS有効での動作確認や、サーバー側がマルチスレッド動作なのに何らかの理由でそれを検出せずZTSが有効にならないときに使うものである。
たまに「worker MPM の場合は--enable-maintainer-ztsが必要」って書いてあるものがWebで見つかるが、これは(昔は知らないが現在では)間違いなので、気をつけよう。
コメント (0) |  トラックバック (0) | 

マルチスレッド対応

2007-02-15 17:48:40 | 変な言葉
「マルチスレッドに対応したエンコードソフト」とか「ゲームはマルチスレッド非対応のものが多いのでデュアルコアは効果がない」とか聞きますが、正直違和感有り有りです。
複数のスレッド→マルチスレッド だから、マルチスレッド対応って言うのは複数のスレッドに対応しているという意味だと思う。これでは、複数のスレッドが用意されていて、それにプログラムが対応しているかのように思える。プレステ2対応のコントローラーってのはプレステ2があって、それにあわせて動いています。
しかし実際には、プログラムが複数のスレッドを生成するのです。(スレッドの生成が実装上どうなってるかは別の話)

「○○対応」というのは誤用されがちな気がします。
コメント (0) |  トラックバック (0) | 

「(女性は)子供を産む機械」なんて誰も言ってないんだけど

2007-01-31 00:17:49 | 未分類
世の中はこの件に関しては批判ばっかりで面白くないので俺はここでは擁護してみよう。

タイトルの通り、誰も「女性は子供を産む機械」(あえて括弧を外したよ)なんていってないんだな。
「産む機械、装置の数は決まっているから、あとは一人頭で頑張ってもらうしかない」と言ったそうだ。

柳沢厚生労働大臣は、理不尽ですが、「物事を単純化して順番に理論を組み立てていく」という考え方ができない人が世の中にはいっぱいいるということを理解しなくてはなりません。

もっとも、この情報操作は悪意に基づくものだという噂もありますが。



俺はいま大学でミクロ経済学を勉強中です。会社は単に労働力と資本からなにか財を生産するブラックボックスと考えて、そこから出てくるいろんな理論を教わりました。
ところが、いるんですよ。「会社はそんなに単純ではない」と言う人が。

俺は高校のとき物理を習いました。例えば、物体に力を加えたときの運動を習いました。
ある人が言いました。「摩擦とか空気抵抗は無視するって言ったってそんなの現実的ではないから意味がない」と。
コメント (3) |  トラックバック (0) | 

しばらく

2007-01-11 20:24:36 | 未分類
しばらく旅に出ます。2月上旬ぐらいまで。
コメント (1) |  トラックバック (0) | 

VMR9でインターレースの動画を再生中にシークするとバグるのを直す方法

2007-01-04 01:27:11 | 未分類
VMR9でインターレースの動画を再生中にシークバーをいじると、タイミングによってインターレースのトップフィールドとボトムフィールドが入れ替わる?ことがある。こうなると、ちらついて非常に見難い。
Media Player Classic を使うようになってからずっとこの症状に悩まされていたのだが、このたび無理やり直す方法を見つけた。

FIX:ちらつくのが Windows XP で有効な DXVA での ビデオ ミキサー レンダラ 9(VMR9)を介してインターレース内容を再生するとき、シークの後、発生することがあります。
Microsoftはいちおうこの件をバグと認識しているようだ。
ここにある「Download the WindowsXP-KB919071-x86-ENU.exe package now.」ってところから修正プログラムが入手できる。しかし、なんとMicrosoftは英語版しかファイルを提供していないようだ。
この問題を解決するには、Microsoft Product Support Services にお問い合わせのうえ、修正プログラムを入手してください。 Microsoft Product Support Services の電話番号一覧およびサポート料金については、次のマイクロソフト Web サイトを参照してください。
ここに電話すれば日本語版のファイルがもらえるのだろうか?でも面倒じゃね?
この件で問題になっている quartz.dll ってのはDirectShowの主要ファイルに過ぎず、日本語のWindowsと英語のWindowsで何が違うのかなーって感じ。まあ一部のエラーメッセージが英語になるぐらいだろう、と軽く考えて、俺は英語版のファイルを日本語Windowsに無理やり適用することにした。

英語版をダウンロードして実行すると、ファイルの展開が始まり、そして
Setup cannot update your Windows XP files because the language installed on your system is different from the update language.
とエラーになった。そこで、エラーダイアログのOKを押さずに展開されたフォルダの中の quartz.dll を適当な場所にコピーしておく。ちなみに展開される場所はうちの環境ではDドライブのルートだった。なぜこんなところに展開されるのか意味が分からないが。エラーダイアログのOKを押すと先ほどのフォルダは消える。
そして、%system%ディレクトリ(C:Windowssystem32など)に quartz.dll をコピーして上書きする。システムファイルの保護機能については各自でうまいことやってください。

さっきも書いたとおり quartz.dll は重要なファイルといえばそうだけど、単に DirectShow のファイルに過ぎないからこういう荒っぽいことをやっても大丈夫だと思う。ただ、やはり正規の方法ではないので、やる場合はよく考えてやってね。
コメント (0) |  トラックバック (0) | 

排他処理に stream_set_write_buffer は不要じゃね?

2007-01-03 00:23:07 | PHP

PHPの話。 「set_file_buffer (stream_set_write_buffer) でバッファを0にしないと排他処理が正常に行われない」なんて感じの記述がgoogleで見つかったり、PHPのユーザーの間で常識のように語られたりするんですが、なんなんでしょうかこれ。

stack*の連載PHP

set_file_buffer という関数では、書き込みバッファを 0 にするという操作をしています。なぜこんなことをするかというと、通常、あるファイルに書き込みをする際には、「バッファ」といわれる、メモリ上にある書き込む内容を一時溜め込むための領域に溜め込みます。そして、ある程度溜まった所で一括してディスクに書き込みます。バッファにある値と、ディスクにある値が異なる瞬間があるわけで、つまり、バッファがあると、せっかく flock を使ってロックしても、書き込まれる前のデータをディスクから読み出してしまうことがあるわけです。

Web Artisan Blog の PHP:ファイルのロック方法(排他制御)の例

注意点としては、"stream_set_write_buffer"関数で、バッファを0にする事。

PHP 実践のツボ 〜セキュアサイト構築テクニック〜(書籍)

同時アクセス対策として排他制御をするには flock関数とset_File_Buffer関数の利用

「バッファにある値と、ディスクにある値が異なる瞬間がある」ってのは正しいね。でもその異なる値をどうやって読み出すのか。flockをしてるんでしょ?俺が作った変な解説図を参考にしてもらいたい。ところで、PHPの公式マニュアルにはこう書いてある。

fwrite() による出力は、通常では 8K バイトがバッファ されます。 これは、もし同じストリームに対し出力を行おうとするプロセスが2つあったとき、 いずれかのプロセスは、他方のプロセスが出力できるように 8K バイト分 データを書き出したところで停止することを示しています。 stream_set_write_buffer() は、stream で指定されたファイルポインタに buffer で表されたバイト数分だけ出力バッファを設定します。 buffer が 0 であれば、書き込み操作はバッファされなく なります。 これにより、fwrite() による書き込み操作が、他の プロセスが同じ出力ストリームに対して何らかの書き込み操作を行う前に 完了することが保証されます。

この記述を誤解していると思います。この記述は、flockやらセマフォやらmutexで排他制御されていない同時書き込みで何が起こるかを書いていて、flockを用いた排他制御の時には関係のない話です。
つまり、'a'モードでfopenしたときとか、ネットワークみたいなシーク不能なストリームに対して、例えば10MBのデータを1回のfwriteで書き込むときに、バッファが有効でなければ対応するOS呼び出し(システムコール)が1回になるとかそういうこと。
(しかし「他方のプロセスが出力できるように 8K バイト分 データを書き出したところで停止する」(英語版: each is paused after 8K of data to allow the other to write )ってのもまた誤解を生む書き方だなあ。)

検証コード(06/01/04にこっそり修正)

<?php
$file2 = fopen('./countbystring', 'a+');
if(!flock($file2, LOCK_EX)) exit(1);
$tmp = fgets($file2);
if(empty($tmp)) $tmp = '0';
$tmp++;

ftruncate($file2, 0);
fwrite($file2, strval($tmp));
fclose($file2);
 
$file1 = fopen('./countbysize', 'a');
fwrite($file1, '0', 1);
fclose($file1);
?>

このコードの前提条件は「flockが成功した場合はきちんと機能する」「追記モードで開いたファイルへの書き込みは全て行われる」。NFSとかのネットワークファイルシステムで行うと2番目の条件が満たされないらしい。
まともなOSでローカルのHDD上とかでこれを実行すれば、countbysize のサイズと countbystring の内容は一致します。 stream_set_write_buffer でバッファを無効にしてないからうまく一致しないという環境は存在するでしょうか?

そういえば、この記事を書くに当たってPHPの排他処理に関してGoogleで調べたんですが、fcloseの前にflockを解除しているプログラムをよく見かけるんですけど、あれは何を意図したものなのでしょうか。flock解除したらその後は他のプロセスが割り込む可能性があります。つまりfcloseの前に他のプロセスが同じファイルに何かするかもしれないんです。たしかに stream_set_write_buffer でバッファを無効にしてれば割り込まれても問題はないかもしれないけど、そんなのは本末転倒で、ストリームに書き込みを行った場合fflushまたはfcloseまでのいつか分からない瞬間に書き込みが行われると考えるのが本来で、fcloseをロックの範囲外に出すという考え方が間違ってます。
fcloseでflockが解除されるのはちゃんと意味があって、「mallocしたらfreeしなきゃいけない」のとは訳が違うんだな。

これまたさっきのstack*の話ですが、企業のサイトなんで少々(タイトルどおり?)暴言吐かせていただきますが

また、r+ でのファイルのオープン時にはファイルポインタ(ファイル中のどこを参照しているかのポインタ)はファイルの先頭にあるのですが、ロックが獲得できるのを待っている間にファイルの状態が変わっている場合があります。そのときにファイルポインタが正しい位置を示すように(この場合ファイルの先頭が正しい位置)fseek や、rewind というファイルポインタの操作関数を使ってファイルポインタのリセットをしてやらないといけません。
いったい何を言ってるんでしょうか。「ファイルポインタ」はストリームごとにある。他のプロセスが何をしようと関係ない。同じプロセス内でも複数回fopenすれば独立の「ファイルポインタ」なのに。全く分かってないですね。
また、set_file_buffer のところをコメントアウトしたりして、いろいろ検証してみてください。
検証しなきゃいけないのはあなたでしょ。本当にこの文章書いた 人は検証したんでしょうかね。まあこんないい加減なこと書くぐらいですから、検証の仕方もダメなんでしょう。

Googleで「PHP 排他処理」で検索するとさっき取り上げたWeb Artisan Blogや stack* はとても上位に来ます。特にstack*は企業のサイトです。こうやって間違いが常識になるわけですね。

コメント (2) |  トラックバック (0) | 

Apacheの設定はgoogle先生は嘘だらけ

2006-12-28 10:45:28 | 未分類
2chを見てたら面白い、素晴らしいページを見つけた。
Apache のドキュメントは熟読せよ
確かにGoogleでApacheの設定を見るよりマニュアルを見たほうが早い。俺はApacheの設定でGoogleを頼りにしたのって最近はないし、まあ本当に使い始めのときは調べたけど、マニュアルの在り処と読み方を理解してからはそっちで調べたほうが早い。Apacheのマニュアルはすごい分かりやすく出来てると思うんだけどなあ。

Googleに聞くことの何が悪いかって、引っかかったページをどんな人が書いたかわからないことだね。Apacheに超詳しい人が設定を解説してくれてるページばっかりならいいんだけど。初心者や、そもそもやる気のないサーバー管理者が「なんかこうやったら動いたよ!」ってのを書いているだけのことが非常に多い。Apacheに詳しい人は、マニュアル見れば分かるような単純なことはいちいちブログにメモしたりしないしね。

あと、Apacheを知らないで単にWebスペースを借りている人が「.htaccess の書き方」を解説していることも多い。.htaccessの仕様は、Apacheをいじり始めれば実はとてもきわめて明快だってわかるけど、そこまでたどり着かなければ、.htaccessはなんかよくわからないあやふやな魔法のファイルみたいなイメージが強い。俺はそうだった。
なんでこうなるかって、レンタルスペース借りてるだけの人にApacheのマニュアル見ろって言っても敷居が高すぎるしねえ。そうなると「.htaccessの書き方」は「インターネットでの口コミ」にならざるを得ない。

困ったことに、Apacheをいじる人まで「インターネットでの口コミ」に頼るんだよね。マニュアルよりある意味わかりやすい面もあり、そのとおりに設定すれば動くし。しかし、動くのと、正しく動くことは別物なのはApache のドキュメントは熟読せよ の<Limit>然り、「AddDefaultCharset none」然り。

しかし、AddDefaultCharset none には爆笑した。
コメント (4) |  トラックバック (0) |