2

我不确定最好的解决方案,但这就是我所做的。

我正在使用 PHP 查看包含 zip 文件的目录。

这些 zip 文件包含要通过 SqlLoader (sqlldr) 加载到 oracle 数据库中的文本文件。

我希望能够通过命令行启动多个 PHP 进程,以将这些 zip 文件加载到数据库中。

如果其他 'php loader' 进程正在运行,它们不应重叠并尝试加载相同的 zip 文件。我知道我可以启动一个进程并让它处理每个 zip 文件,但我宁愿为传入的 zip 文件启动一个新进程,以便我可以同时加载。

现在,我创建了一个类,该类将通过创建一个名为“filename.ext.lock”的文件来“锁定”一个 zip 文件、一个目录或一个通用文本文件。启动的其他进程将检查文件是否已以这种方式“锁定”,如果有,它将跳过该文件并移至另一个文件进行处理。

我创建了一个使用目录并创建“进程 ID”文件的类,以便每个 PHP 进程都有一个 ID,可用于记录目的和识别哪个 PHP 进程已锁定文件。

我在一台 Windows 机器上,对于那些可能建议使用 pcntl 的人来说,它不在计划中让它成为一台 ubuntu 机器。

您还看到了哪些其他解决方案?我知道这并不是真正同步的,因为可能即将创建一个锁定文件,然后发生上下文切换,然后另一个 PHP 进程在第一个 PHP 进程可以创建锁定文件之前“锁定”该文件。

您能否提供一些有关如何使此解决方案更好的想法?一个java实现?二郎?

还忘了提到,PHP 进程连接到数据库以获取有关它将通过 SqlLoader 加载的文件的元数据。我认为这并不重要,但以防万一。

快速说明:我知道 sqlldr 会锁定它正在加载的表,如果多个进程尝试加载到同一个表,它将成为瓶颈。为了缓解这个问题,我计划在当前加载的表之后创建一个包含文件名的目录。表加载完成后,相应的文件将被删除,其他进程将检查加载该表是否安全。

额外信息:我使用 7zip 解压缩文件和 php 的 exec 来执行这些命令。

我也在使用 exec 来调用 sqlldr 。

zip 文件可能很大 (1gb),加载一个表可能需要 1 小时。

4

2 回答 2

0

不知道我理解对不对,不过我有个建议:获取带有优先级前缀的锁文件。

示例: 10-script.php启动

20-script.php开始(进入循环等待10-foobar.ext.lock

10-foobar.ext.lock不是由10-script.php生成的,仍在等待

30-script.php将不得不等待10-foobar.ext.lock20-example.ext.lock

我试图用 cygwin 找到 pcntl_fork,但没有发现任何有用的东西

于 2011-09-13T04:19:50.010 回答
0

您可以在加载程序开始处理 zip 文件时重命名 zip 文件,而不是创建 .lock 文件。例如“foobar.zip.bar”,这个过程应该比在磁盘上创建一个新文件要快。

但它并不能确保您的下一个加载程序将在文件重命名后加载。您至少应该有一些控件在另一个脚本中加载新的加载器。

此外,只是一些建议,可以使用 CURL 在 PHP 中模拟线程,您可能想尝试一下。

https://web.archive.org/web/20091014034235/http://www.ibuildings.co.uk/blog/archives/811-Multithreading-in-PHP-with-CURL.html

于 2011-09-14T14:18:51.067 回答