从bash中的文件维护一组并发作业w / args

时间:2015-02-24 16:07:43

标签: 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

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

2 个答案:

答案 0 :(得分:3)

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

第二:启动ps以检查孩子是否容易出现误报(将php的无关调用视为当前流程中的工作),如果在循环中完成则效率极低(因为每次调用都涉及fork()/ exec()/ wait()循环)。


因此,不要那样做:使用带有-P的GNU xargs版本,或者(如果必须)使用GNU并行版本。

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

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

...或者,对于纯POSIX shell:

xargs -d "
" -n 1 -P 250 php b <targets

答案 1 :(得分:1)

使用GNU Parallel,它看起来像这样(选择你最喜欢的风格):

cat targets | parallel -P 250 php b
parallel -a targets -P 250 php b
parallel -P 250 php b :::: targets

如果有其他php进程在运行,则不存在误报的风险。与xargs不同,如果文件targets包含空格“或”,则不存在风险。