【问题标题】:Storing data in /tmp from a forked process in php从 php 中的分叉进程将数据存储在 /tmp 中
【发布时间】:2012-07-11 14:12:41
【问题描述】:

现在,我一直将来自分叉进程的序列化对象存储在 /tmpfile_put_contents 中。

一旦所有子进程结束,我只需使用file_get_contents 并反序列化数据来重建我的对象以进行处理。

所以我的问题是,有没有更好的方法来存储我的数据而不写入 /tmp?

【问题讨论】:

  • 这些数据是基于每个会话的吗?
  • 每次运行脚本时都会使用新数据。

标签: php fork tmp


【解决方案1】:

除了将数据存储在文件中之外,唯一想到的其他原生解决方案是 shm http://www.php.net/manual/en/function.shm-attach.php 或套接字流对 http://www.php.net/manual/en/function.stream-socket-pair.php

如果在脚本运行后收集的数据不重要,这两种方法都应该是可行的。它们背后的想法是在您的父进程和子进程之间打开一个通信通道。我会说,我个人的看法是,除非使用文件系统出现某种问题,否则它是迄今为止最不复杂的解决方案。

SHM

使用 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

【讨论】:

    【解决方案2】:

    您可以使用更快的共享内存缓存,例如 memcached,但取决于您正在做什么以及数据的敏感度/重要性,基于文件的解决方案可能是您的最佳选择。

    【讨论】:

    • 数据不敏感。只需根据模型类型计算服务器的功耗。无论如何,我将不得不考虑 memcache 选项。我应该说我正在寻找一个更原生的解决方案。也许使用 php 可用的东西。
    • 我认为 Pekka 有一个很好的观点。由于这些数据是基于会话的,所以 memcache 似乎有点矫枉过正。因此,还有其他创造性的解决方案吗?
    • @austin 我认为矫枉过正是相对的,如果它是基于会话的,那么 memcache 将非常合适,因为数据将是短暂的 :) 我认为存储跨进程数据的需求并不大在 PHP 中,就像我之前说的,如果你不想使用 memcache,也许基于文件的解决方案是最好的!
    猜你喜欢
    • 2010-11-07
    • 1970-01-01
    • 2011-08-15
    • 2018-08-24
    • 1970-01-01
    • 2012-11-16
    • 1970-01-01
    • 2019-01-17
    • 1970-01-01
    相关资源
    最近更新 更多