编辑:我已经在一个希望得到更多的响应标记的这款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

这将是每用户其的可以的是你想要的呢。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top