一段时间以来,我一直在将来自分叉进程的序列化对象存储/tmp
在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
}
我个人喜欢使用这些进行进程间通信。这个想法是在分叉之前,您创建一个流套接字对。这导致创建了两个相互连接的读写套接字。其中一个应该由父母使用,其中一个应该由孩子使用。您必须为每个孩子创建一个单独的配对,它会稍微改变您父母的模型,因为它需要更实时地管理通信。
幸运的是,这个函数的 PHP 文档有一个很好的例子:http ://us2.php.net/manual/en/function.stream-socket-pair.php
您可以使用更快的共享内存缓存,例如 memcached,但取决于您正在做什么以及数据的敏感度/重要性,基于文件的解决方案可能是您的最佳选择。