しばらくの間、フォークされたプロセスからシリアライズされたオブジェクトを/tmp
withに保存してきましたfile_put_contents
。
すべての子プロセスが終了したらfile_get_contents
、データを使用してシリアル化を解除し、オブジェクトを再構築して処理します。
私の質問は、/tmp に書き込まずにデータを保存するより良い方法はありますか?
データをファイルに保存する以外に、頭に浮かぶ他のネイティブソリューションは、shm http://www.php.net/manual/en/function.shm-attach.phpまたはソケットストリームペアhttp://wwwです。 .php.net / manual / en / function.stream-socket-pair.php
スクリプトの実行後に収集されたデータが重要でない場合は、これらのいずれかを実行できるはずです。両方の背後にある考え方は、親プロセスと子プロセスの間の通信チャネルを開くことです。私の個人的な意見は、ファイルシステムを使用する何らかの問題がない限り、それがはるかに最も複雑でない解決策であるということです。
shmの考え方は、シリアル化されたオブジェクトをファイルに格納する代わりに、セマフォによって並行性が保護されているshmセグメントに格納するというものです。コードを許してください、それは大まかなですが、あなたに一般的な考えを与えるのに十分であるはずです。
/*** Configurations ***/
$blockSize = 1024; // Size of block in bytes
$shmVarKey = 1; //An integer specifying the var key in the shm segment
/*** In the children processes ***/
//First you need to get a semaphore, this is important to help make sure you don't
//have multiple child processes accessing the shm segment at the same time.
$sem = sem_get(ftok(tempnam('/tmp', 'SEM'), 'a'));
//Then you need your shm segment
$shm = shm_attach(ftok(tempnam('/tmp', 'SHM'), 'a'), $blockSize);
if (!$sem || !$shm) {
//error handling goes here
}
//if multiple forks hit this line at roughly the first time, the first one gets the lock
//everyone else waits until the lock is released before trying again.
sem_acquire($sem);
$data = shm_has_var($shm, $shmVarKey) ? shm_get_var($shm, $shmVarKey) : shm_get_var($shm, $shmVarKey);
//Here you could key the data array by probably whatever you are currently using to determine file names.
$data['child specific id'] = 'my data'; // can be an object, array, anything that is php serializable, though resources are wonky
shm_put_var($shm, $shmVarKey, $data); // important to note that php handles the serialization for you
sem_release($sem);
/*** In the parent process ***/
$shm = shm_attach(ftok(tempnam('/tmp', 'SHM'), 'a'), $blockSize);
$data = shm_get_var($shm, $shmVarKey);
foreach ($data as $key => $value)
{
//process your data
}
私は個人的にこれらをプロセス間通信に使用するのが大好きです。アイデアは、フォークする前に、ストリームソケットペアを作成することです。これにより、相互に接続された2つの読み取り/書き込みソケットが作成されます。それらの1つは親が使用する必要があり、もう1つは子が使用する必要があります。子ごとに個別のペアを作成する必要があります。これにより、通信をもう少しリアルタイムで管理する必要があるという点で、親のモデルが少し変更されます。
幸い、この関数のPHPドキュメントには素晴らしい例があります:http://us2.php.net/manual/en/function.stream-socket-pair.php
高速な memcached などの共有メモリ キャッシュを使用することもできますが、実行内容やデータの機密性や重要性によっては、ファイル ベースのソリューションが最適な選択肢になる場合があります。