我想让我的代码的一部分更有效率.我正在考虑将它分成多个进程并让它们一次执行50/100次而不是一次.
例如(伪):
for line in file;
do
foo;
foo2;
foo3;
done
Run Code Online (Sandbox Code Playgroud)
我想这个for循环运行多次.我知道这可以通过分叉来完成.它看起来像这样吗?
while(x <= 50)
parent(child pid)
{
fork child()
}
child
{
do
foo; foo2; foo3;
done
return child_pid()
}
Run Code Online (Sandbox Code Playgroud)
或者我是否以错误的方式思考这个问题?
谢谢!
Ale*_*huk 52
在bash脚本(非交互式)中,默认情况下JOB CONTROL被禁用,因此您无法执行命令:job,fg和bg.
这对我有用:
#!/bin/sh
set -m # Enable Job Control
for i in `seq 30`; do # start 30 jobs in parallel
sleep 3 &
done
# Wait for all parallel jobs to finish
while [ 1 ]; do fg 2> /dev/null; [ $? == 1 ] && break; done
Run Code Online (Sandbox Code Playgroud)
最后一行使用"fg"将后台作业带到前台.它在一个循环中执行此操作,直到fg返回1($?== 1),它在不再有任何后台作业时执行.
mob*_*mob 29
我不知道fork在bash中有任何明确的调用.您可能想要做的是附加&
到要在后台运行的命令.您还可以使用&在bash脚本中定义的函数:
do_something_with_line()
{
line=$1
foo
foo2
foo3
}
for line in file
do
do_something_with_line $line &
done
Run Code Online (Sandbox Code Playgroud)
编辑:为了限制同时后台进程的数量,你可以尝试这样的事情:
for line in file
do
while [`jobs | wc -l` -ge 50 ]
do
sleep 5
done
do_something_with_line $line &
done
Run Code Online (Sandbox Code Playgroud)
Ole*_*nge 18
使用GNU Parallel,您可以:
cat file | parallel 'foo {}; foo2 {}; foo3 {}'
Run Code Online (Sandbox Code Playgroud)
这将在每个cpu核心上运行一个作业.运行50做:
cat file | parallel -j 50 'foo {}; foo2 {}; foo3 {}'
Run Code Online (Sandbox Code Playgroud)
观看介绍视频以了解更多信息:
http://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
har*_*dsv 17
我不喜欢使用,wait因为它会在进程退出之前被阻塞,这在有多个进程需要等待时并不理想,因为在当前进程完成之前我无法获得状态更新.我更喜欢使用kill -0和之相结合sleep.
鉴于pids要等待的数组,我使用以下waitPids()函数来获得有关哪些pids仍未完成的持续反馈.
declare -a pids
waitPids() {
while [ ${#pids[@]} -ne 0 ]; do
echo "Waiting for pids: ${pids[@]}"
local range=$(eval echo {0..$((${#pids[@]}-1))})
local i
for i in $range; do
if ! kill -0 ${pids[$i]} 2> /dev/null; then
echo "Done -- ${pids[$i]}"
unset pids[$i]
fi
done
pids=("${pids[@]}") # Expunge nulls created by unset.
sleep 1
done
echo "Done!"
}
Run Code Online (Sandbox Code Playgroud)
当我在后台启动一个进程时,我pids使用下面的实用程序函数将其pid立即添加到数组中:
addPid() {
local desc=$1
local pid=$2
echo "$desc -- $pid"
pids=(${pids[@]} $pid)
}
Run Code Online (Sandbox Code Playgroud)
以下示例说明如何使用:
for i in {2..5}; do
sleep $i &
addPid "Sleep for $i" $!
done
waitPids
Run Code Online (Sandbox Code Playgroud)
以下是反馈的内容:
Sleep for 2 -- 36271
Sleep for 3 -- 36272
Sleep for 4 -- 36273
Sleep for 5 -- 36274
Waiting for pids: 36271 36272 36273 36274
Waiting for pids: 36271 36272 36273 36274
Waiting for pids: 36271 36272 36273 36274
Done -- 36271
Waiting for pids: 36272 36273 36274
Done -- 36272
Waiting for pids: 36273 36274
Done -- 36273
Waiting for pids: 36274
Done -- 36274
Done!
Run Code Online (Sandbox Code Playgroud)
让我尝试一下例子
for x in 1 2 3 ; do { echo a $x ; sleep 1 ; echo b $x ; } & done ; sleep 10
Run Code Online (Sandbox Code Playgroud)
并用于jobs查看正在运行的内容。
| 归档时间: |
|
| 查看次数: |
112707 次 |
| 最近记录: |