并发下php脚本执行,尝试php命令行脚本多进程并发执行

php不支持多线程,但是我们可以把问题转换成“多进程”来解决。由于php中的pcntl_fork只有unix平台才可以使用,所以本文尝试使用popen来替代。

下面是一个例子:

被并行调用的子程序:

if($argc==1){

echo("argv\n");

}

$arg = $argv[1];

for($i=0; $i<10; $i++)

{

echo($i.".1.".time()." exec $arg \n");

if($arg==‘php2‘)

{

sleep(1);

echo($i.".2.".time()." exec $arg \n");

sleep(1);

}else{

sleep(1);

}

?>

----------------------------

主调用者程序,由他调用子进程,同时并发的收集子程序的输出

error_reporting(E_ALL);

$handle1 = popen(‘php sub.php php1‘, ‘r‘);

$handle2 = popen(‘php sub.php php2‘, ‘r‘);

$handle3 = popen(‘php sub.php php3‘, ‘r‘);

echo "‘$handle1‘; " . gettype($handle1) . "\n";

echo "‘$handle2‘; " . gettype($handle2) . "\n";

echo "‘$handle3‘; " . gettype($handle3) . "\n";

//sleep(20);

while(!feof($handle1) || !feof($handle2) || !feof($handle3) ){

$read = fgets($handle1);

echo $read;

$read = fgets($handle2);

echo $read;

$read = fgets($handle3);

echo $read;

}

pclose($handle1);

pclose($handle2);

pclose($handle3);

?>

-------------------

下面是我机器上的输出:

> php exec.php

‘Resource id #4‘; resource

‘Resource id #5‘; resource

‘Resource id #6‘; resource

0.1.1147935331 exec php1

0.1.1147935331 exec php2

0.1.1147935331 exec php3

1.1.1147935332 exec php1

0.2.1147935332 exec php2

1.1.1147935332 exec php3

2.1.1147935333 exec php1

1.1.1147935333 exec php2

2.1.1147935333 exec php3

3.1.1147935334 exec php1

1.2.1147935334 exec php2

3.1.1147935334 exec php3

4.1.1147935335 exec php1

2.1.1147935335 exec php2

4.1.1147935335 exec php3

5.1.1147935336 exec php1

2.2.1147935336 exec php2

5.1.1147935336 exec php3

6.1.1147935337 exec php1

3.1.1147935337 exec php2

6.1.1147935337 exec php3

7.1.1147935338 exec php1

3.2.1147935338 exec php2

7.1.1147935338 exec php3

8.1.1147935339 exec php1

4.1.1147935339 exec php2

8.1.1147935339 exec php3

9.1.1147935340 exec php1

4.2.1147935340 exec php2

9.1.1147935340 exec php3

5.1.1147935341 exec php2

5.2.1147935342 exec php2

6.1.1147935343 exec php2

6.2.1147935344 exec php2

7.1.1147935345 exec php2

7.2.1147935346 exec php2

8.1.1147935347 exec php2

8.2.1147935348 exec php2

9.1.1147935349 exec php2

9.2.1147935350 exec php2

**总结:**

**主程序循环等待子进程, 通过fgets或fread 把子进程的输出获取出来 , 从时间戳上看,的确实现了并发执行。**

-----------------------------------------------

改进:

*  popen打开的句柄是单向的,如果需要向子进程交互,可以使用proc_open

*  使用数组和子函数代替while(!feof($handle1) || !feof($handle2) || !feof($handle3) )这种龌龊的写法

*  用fread一次把子进程已经产生的输出取完,而不是每次一行。

这是另一个改进:

一个并发执行shell任务的调度者,本程序读取一个任务文件,把里面的每行命令并发执行, 可以设置同时存在的子进程数目:

/*

主任务管理器

并发的执行子任务列表

*/

include("../common/conf.php");

include("../common/function.php");

//开启的进程数

$exec_number = 40 ;

/***** main ********/

if($argc==1){

echo("argv\n");

}

$taskfile = $argv[1];

//tasklist

$tasklist = file($taskfile);

$tasklist_len = count($tasklist);

$tasklist_pos = 0;

$handle_list = array();

while(1){

//子进程列表有空闲,则填充补齐子进程列表

if($exec_number > count($handle_list) &&

$tasklist_pos 

{

for($i=$tasklist_pos; $i

{

$command = $tasklist[$i] ;

$handle_list[] = popen($command , "r" );

tolog("begin task \t ".$tasklist[$i]);

$i++;

if($exec_number == count($handle_list)) break;

}

$tasklist_pos = $i;

}

//如果子进程列表空,退出

if(0 == count($handle_list))

{

break;

}

//检查子进程列表的输出,把停掉的子进程关闭并记录下来

$end_handle_keys = array();

foreach($handle_list as $key => $handle)

{

//$str = fgets($handle, 65536);

$str = fread($handle, 65536);

echo($str);

if(feof($handle))

{

$end_handle_keys[] = $key;

pclose($handle);

}

}

//踢出停掉的子进程

foreach($end_handle_keys as $key)

{

unset($handle_list[$key]);

//var_dump($handle_list);

//exit;

}

}

tolog("\n\n*******************end**********************\n\n", "" ,     true);

?>

原文:http://www.cnblogs.com/wish123/p/3947718.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 自动执行Windows命令行脚本可以通过Windows自带的批处理文件(.bat)或者PowerShell脚本来实现。 使用批处理文件,你可以将一系列Windows命令行命令写在一个文件里,然后将文件保存为.bat文件。执行这个文件就会依次执行其中的命令。 使用PowerShell脚本,你可以利用PowerShell的脚本语言编写一个脚本文件,然后执行这个脚本文件来执行一系列命令。PowerShell相对于批处理文件来说更加强大和灵活,可以进行更多的操作和处理。 无论使用哪种方式,你可以将脚本文件放在Windows计划任务中,指定执行的时间和频率,这样就可以自动地执行Windows命令行了。 ### 回答2: 自动执行Windows命令行脚本是一种批处理脚本,也被称为批处理文件。它是一种文本文件,其中包含一系列要在Windows命令提示符中执行的命令。通过编写批处理脚本,我们可以实现自动化执行一系列操作的目的。 使用Notepad或其他文本编辑器可以创建一个批处理脚本脚本的文件扩展名通常为".bat"或".cmd"。在脚本中,我们可以使用各种Windows命令行命令,例如"cd"用于更改目录,"dir"用于列出文件和文件夹,"copy"用于复制文件等。我们可以根据需要在脚本中添加多个命令。 要执行一个批处理脚本,我们只需要双击脚本文件,Windows会自动打开一个新的命令提示符窗口,并按顺序执行脚本中的命令。执行期间,我们可以在命令提示符窗口中看到每个命令的输出结果。 自动执行Windows命令行脚本具有很多优点。首先,它可以大大减少人工反复执行命令的工作量。其次,我们可以将一系列常用的操作组合在一个脚本中,一次性执行,提高了工作效率。此外,批处理脚本也可以用于自动化一些重复性任务,例如创建备份,安装软件等。 总之,自动执行Windows命令行脚本是一种方便实用的工具,可以帮助我们更高效地管理和执行各种命令行操作。无论是个人使用还是在企业环境中都有广泛的应用。 ### 回答3: 自动执行Windows命令行脚本是一种用于自动化执行一系列Windows命令的文件。它可以通过编写一些特定的命令和指令,让计算机在特定条件或时间间隔下自动执行这些命令,从而实现一些批量操作,提高工作效率。 为了创建一个这样的脚本,我们可以使用Windows自带的命令行工具“cmd.exe”或者PowerShell来编写脚本文件。脚本文件通常使用扩展名为“.bat”或“.cmd”。 在脚本文件中,我们可以编写一系列需要执行的命令,比如复制文件、重命名文件、删除文件、运行程序等等。可以通过添加条件判断、循环语句和参数传递等让脚本更加灵活和实用。 例如,如果我们想要每天定时备份某个文件夹中的数据,可以创建一个脚本来实现自动备份。首先,我们可以使用命令行命令“xcopy”复制文件夹中的文件到备份目录;然后,可以使用“date”和“time”命令获取当前日期和时间;最后,将复制的文件和备份时间记录到日志文件中。 当脚本文件准备好后,我们可以设置计划任务,让操作系统在指定时间自动执行脚本。通过计划任务,我们可以实现定时备份、定时清理、定时运行程序等各种自动化操作。 自动执行Windows命令行脚本大大简化了一些繁琐的操作,提高了工作效率。它可以自动处理一些重复性的任务,并且具有灵活、可定制的特点,能够根据不同的需求编写不同的脚本。因此,掌握如何编写和使用这样的脚本对于Windows系统的管理和应用开发来说都是非常有用的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值