我怎么能强制执行分叉儿的最高金额是多少?
-
22-07-2019 - |
题
编辑:我已经在一个希望得到更多的响应标记的这款C。它更多的理论我感兴趣的不是具体的语言实现。所以,如果你是一个C编码器,请把下面的PHP伪代码,并随时用C语言编写的答案回应。
我想有它并行而不是串行执行其任务,以加快PHP CLI脚本。的任务是完全相互独立的,从而它并不重要,他们开始该顺序/光洁度。
这里的原始脚本(注意,所有这些实施例被剥离的,为了清楚起见):
<?php
$items = range(0, 100);
function do_stuff_with($item) { echo "$item\n"; }
foreach ($items as $item) {
do_stuff_with($item);
}
我已经设法使其在$items
平行 pcntl_fork()
如下所示工作:
<?php
ini_set('max_execution_time', 0);
ini_set('max_input_time', 0);
set_time_limit(0);
$items = range(0, 100);
function do_stuff_with($item) { echo "$item\n"; }
$pids = array();
foreach ($items as $item) {
$pid = pcntl_fork();
if ($pid == -1) {
die("couldn't fork()");
} elseif ($pid > 0) {
// parent
$pids[] = $pid;
} else {
// child
do_stuff_with($item);
exit(0);
}
}
foreach ($pids as $pid) {
pcntl_waitpid($pid, $status);
}
现在我要扩展这个所以有一个最大的,比方说,10个孩子活跃的一次。什么是处理这个的最佳方式?我已经尝试了一些东西,但没有多少运气。
解决方案
有没有系统调用来获得孩子的PID的列表,但ps
能为你做到这一点。
--ppid
开关将列出所有的孩子为你处理,所以你只需要通过计数输出ps
的行数。
另外,您可以维护自己的柜台,你将在fork()
和减量上SIGCHLD
信号增加,假设ppid
停留fork'ed处理保持不变。
其他提示
我能想出的最好的事情是把所有的任务添加到队列中,推出你想要的最大线程数,然后让每个线程请求队列中的任务,执行任务,并请求下一个。不要忘了有当没有更多的任务做线程终止。
分岔是昂贵的操作。从外观上来看,你真正想要的是多线程,没有多的处理。不同的是,螺纹是不是过程重量轻得多,因为线程共享的虚拟地址空间,但工艺具有单独的虚拟地址空间。
我不是一个PHP开发人员,但快速谷歌搜索显示,PHP不支持多线程本身,但也有图书馆做的工作。
不管怎么说,一旦你弄清楚如何生成线程,你应该找出多少个线程产卵。为了做到这一点,你需要知道你的应用程序的瓶颈是什么。是瓶颈CPU,内存或I / O?您在您的评论已经表明,你是网络的约束,并且网络是一种类型的I / O。
如果你是CPU绑定,你只会为你的CPU内核获得尽可能多的并行性;任何更多的线程,你只是在浪费时间做上下文切换。假设你能找出多少总线程产卵,你应该将你的工作分成许多单位,并让每个线程处理一个独立单位。
如果你的内存限制,那么多线程不会帮助。
既然你是I / O瓶颈,找出多少个线程产卵有点麻烦。如果所有的工作项目大约需要同时具备非常低方差来处理,你可以估计有多少线程通过测量一个工作项目需要多久才能产卵。然而,由于网络数据包倾向于具有高度可变的等待时间,这是不太可能的情况下。
一种选择是使用线程池 - 创建一大堆的线程,然后对每个项目来处理,你看看有没有在池中自由线程。如果有,你有一个线程执行的工作,和你移动到下一个项目。否则,等待线程变得可用。选择线程池的大小是很重要的 - 太大了,你是在浪费时间做不必要的上下文切换。太少,和你等待的线程太多。
另一个选择是放弃多线程/多,只是做异步I / O代替。既然你提到你在一个单核处理器的工作,这将可能是最快的选项。您可以使用如 socket_select()
功能测试是否插槽有可用的数据。如果是这样,你可以读取数据,否则你移动到不同的插座。这需要做更多的簿记,但你避免等待数据来在一个插座时,数据可在不同的插座上。
如果你想避开线程和异步I / O,并与多棒,它仍然是值得的,如果每个项目的处理是够贵的。那么你可能做的工作分工,像这样:
$my_process_index = 0;
$pids = array();
// Fork off $max_procs processes
for($i = 0; $i < $max_procs - 1; $i++)
{
$pid = pcntl_fork();
if($pid == -1)
{
die("couldn't fork()");
}
elseif($pid > 0)
{
// parent
$my_process_index++;
$pids[] = $pid
}
else
{
// child
break;
}
}
// $my_process_index is now an integer in the range [0, $max_procs), unique among all the processes
// Each process will now process 1/$max_procs of the items
for($i = $my_process_index; $i < length($items); $i += $max_procs)
{
do_stuff_with($items[$i]);
}
if($my_process_index != 0)
{
exit(0);
}
人的setrlimit 2
这将是每用户其的可以的是你想要的呢。