Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从bash中的文件维护一组带有参数的并发作业_Bash - Fatal编程技术网

从bash中的文件维护一组带有参数的并发作业

从bash中的文件维护一组带有参数的并发作业,bash,Bash,我在网上找到了这个脚本,我不知道在bash中工作太多太奇怪了,但是 这是我的剧本: CONTOR=0 for i in `cat targets` do CONTOR=`ps aux | grep -c php` while [ $CONTOR -ge 250 ];do CONTOR=`ps aux | grep -c php` sleep 0.1 done if [ $CONTOR -le 250 ]; then php b $i > /dev/null & fi done

我在网上找到了这个脚本,我不知道在bash中工作太多太奇怪了,但是

这是我的剧本:

CONTOR=0
for i in `cat targets`
do
CONTOR=`ps aux | grep -c php`

while [ $CONTOR -ge 250 ];do
CONTOR=`ps aux | grep -c php`
sleep 0.1
done

if [ $CONTOR -le 250 ]; then
php b $i > /dev/null &
fi

done

我的目标是URL,b php文件是一个将一些链接保存到文件中的爬虫程序。问题是最大线程数是50-60,这是因为爬虫程序完成得非常快,bash脚本代码没有时间打开我所有的250个线程。是否有机会打开所有线程(250)?每个ps-aux进程可以运行多个线程吗?右知道似乎他在执行ps-aux之后打开了1个线程。

首先:Bash没有任何多线程支持
foo&
启动一个单独的进程,而不是线程

第二:启动
ps
检查子项既容易出现误报(将与
php
无关的调用视为当前进程中的作业),又在循环中执行时效率极低(因为每次调用都涉及fork()/exec()/wait()循环)


因此,不要这样做:使用带有
-p
的GNUxargs版本,或者(如果必须)GNUparallel

假设您的
目标
文件是以换行符分隔的,并且没有特殊的引号或字符,这可能非常简单:

xargs -d $'\n' -n 1 -P 250 php b <targets

xargs-d$'\n'-n1-p250phpb

使用GNU并行时,看起来是这样的(选择您最喜欢的样式):


如果有其他
php
进程正在运行,则不会出现误报风险。与
xargs
不同的是,如果文件
目标
包含空间,则没有风险,“或.

fwiw,
pgrep-cpp
将比
ps | grep
组合更可靠,效率更低。但是xargs/parallel更好。效率不是问题,就像其他人运行php时所发生的情况一样……请注意,
-d$'\n'
构造并不能在每个shell(例如csh、ash、sash、dash和sh)中都起作用。(GNU并行将起作用:-)@OleTange,…严格地说是语法糖;可以键入
,并在任何兼容POSIX的shell中具有相同的效果。而且一个没有bash可用的系统(即使不是默认的)也不可能并行安装GNU。@CharlesDuffy只是为了完整性:它仍然不能在tcsh和csh中工作(这似乎是NetBSD 6.1.3中的默认shell)。即使在当前的框架中,优化也肯定是可能的。例如,为什么要检查
ps
,直到您开始至少250个作业之后再检查呢?
xargs
如果与
-0
(以及适当格式的输入一起使用,这是合适的,如果我们试图做到学究式的正确,因为UNIX文件名可以包含换行符)或
-d$'\n'
。诚然,GNU扩展是必需的,但是。。。嗯,
parallel
甚至不是一个扩展,而是一个全新的程序。“xargs也没有这种风险,如果与-0一起使用”我的观点正是:每次使用xargs时都需要格外小心。GNU并行的情况并非如此。只有当您有将\n放入文件名的恶意用户时(在我担任系统管理员的15年多时间里,我还没有看到普通用户这样做),您才必须使用-0。然而,空格和通常被普通用户使用。不仅仅是恶意的。我在个人经历中看到的一个坏文件名导致的数据丢失是一个缓冲区溢出,将随机垃圾放入一个名称中。也就是说——我对GNU parallel的真正不满在于它的实现;这是一个巨大的、无法读取的perl混乱--”“没有明显的bug”,而不是“显然没有bug”。我很难相信它。不过,我已经把反对意见放在心上,并在回答中给出的xargs行中添加了
-d$'\n'
xargs -d "
" -n 1 -P 250 php b <targets
cat targets | parallel -P 250 php b
parallel -a targets -P 250 php b
parallel -P 250 php b :::: targets