我有一个 FIFO 问题:
为什么是先进先出线程数限制2个,但是进程数,持续增长,一个进程结束,两个进程启动,然后得到3个进程。
持续增长2n-1
#!bin/bash
#exec clear file
mkdir -p xxx
thread_num=2
[ ! -p tmp ] && mkfifo tmp
exec 9<>tmp
for ((i=0;i<$thread_num;i++)); do
echo >&9
done
echo "================start sh===================="
for i in `cat shfiles.txt`;
do
read -u 9
{
sh $i
mv $i xxx/
echo >&9
} &
done
wait
exec 9>&-
rm tmp
echo "=================done===================="
exit 0
@Paul_Pedant
我现在无法添加评论。此代码经过简化,我使用 root 帐户在文件夹中执行它。
shfiles.txt
是 SH 文件路径的集合。
执行的文件中是perforce命令,如下所示:
20210326/archive13.sh
20210326/archive14.sh
p4 archive -D depot -t xxxxx#1
我习惯于ps -aux | grep sh
查看当前的进程,它正在增长和结束。
每个进程结束时都会生成两个进程。所以流程越来越多。
我似乎已经解决了这个问题,但我不知道为什么。修改 fifo 9 -> 7,如 exec 7<>tmp。那9被其他进程使用了吗?
谢谢大家对我的帮助。我有这样的ps
sh -x ShArchiveCommand.sh
sh -x ShArchiveCommand.sh
sh -x ShArchiveCommand.sh
20210326/ArchiveTList12.sh
20210326/ArchiveTList13.sh
然后一小时后
sh -x ShArchiveCommand.sh
sh -x ShArchiveCommand.sh
20210326/ArchiveTList12.sh
sh -x ShArchiveCommand.sh
20210326/ArchiveTList14.sh
sh -x ShArchiveCommand.sh
20210326/ArchiveTList15.sh
我检查 ArchiveTList12 尚未完成
一个新的例外
sh -x ShArchiveCommand.sh
sh -x ShArchiveCommand.sh
20210326/ArchiveTList12.sh
sh -x ShArchiveCommand.sh
20210326/ArchiveTList13.sh
sh -x ShArchiveCommand.sh
20210326/ArchiveTList14.sh
我检查ArchiveTList12,ArchiveTList13没有全部完成
答案1
有趣的方法,所以我遵循了它。
我有一个说明操作的诊断脚本。特别是,它为每个 Tick(“允许运行”)标记了序列号和时间,例如[4] Sent 19:53:54
,因此当读取时,可以识别它。当序列结束时shfiles.txt
,我也会刷新剩余的蜱虫。
我还用前缀标记了所有调试[ x ] &&
。这些行可以永久删除,或者只是通过将 x 更改为空格来禁用。我更改了所有文件名。
我的命令文件moonie.cmds
是这样的(每个命令都标识自己并使调度变得不规则):
echo One && sleep 8
echo Two && sleep 3
echo Three && sleep 6
echo Four && sleep 5
echo Five && sleep 9
这些是简单的命令,我使用bash -c
.脚本名称应该没问题,但 .cmds 文件中的参数和引用可能很困难。我不明白为什么你的mv
脚本(?)运行后到另一个目录,因为我不知道你的.cmds
文件是什么样的。
我曾经pstree
展示过,我的 bash 和外部脚本 pid 是恒定的,异步子 shell 和 sleep 一次运行两个,由变量配置threads
。我用 1、2、3 和 10 个线程进行了测试。
我的脚本是这样的:
#! /bin/bash
Threads=2
mkdir -p moonie.dir #.. Not used.
#.. Clean the named pipe and attach to fd9.
rm -f moonie.fifo
mkfifo moonie.fifo
exec 9<>moonie.fifo
#.. Seed the fifo with required thread count.
for ((Seq = 1; Seq <= Threads; ++Seq)); do
printf '[%s] Sent %(%T)T\n' "${Seq}" -1 >&9
done
echo "================ start sh ===================="
[ x ] && sleep 1 #.. Show we are waiting for the Ticks.
while IFS='' read -r Cmd; do #.. Work through the command list.
IFS='' read -r -u 9 Tick #.. Wait for a free thread.
[ x ] && printf '%(%T)T Read Tick %s\n' -1 "${Tick}"
{ #.. Launch a thread asynchronously.
[ x ] && printf '%(%T)T Begin %s\n' -1 "${Cmd}"
bash -c "${Cmd}"
[ x ] && printf '%(%T)T Ended %s\n' -1 "${Cmd}"
#.. Refresh its thread on completion.
printf '[%s] Sent %(%T)T\n' "${Seq}" -1 >&9
} &
(( ++Seq )) #.. Number Ticks for diagnostics.
[ x ] && sleep 0.3 #.. Wait for the job to register.
[ x ] && pstree -p "${PPID}" #.. Show the running job hierarchy.
done < moonie.cmds
wait #.. Wait for all threads to complete.
#.. Flush superfluous Ticks (timeout read because the fifo will hang).
while IFS='' read -r -t 1 -u 9 Tick; do
[ x ] && printf '%(%T)T Discard Tick %s\n' -1 "${Tick}"
done
exec 9>&- #.. Disconnect and remove the fifo.
rm moonie.fifo
echo "================= done ===================="
exit 0
调试会话是这样的:
================ start sh ====================
19:53:51 Read Tick [1] Sent 19:53:50
19:53:51 Begin echo One && sleep 8
One
bash(12037)───moonie(16150)─┬─moonie(16155)───sleep(16157)
└─pstree(16158)
19:53:51 Read Tick [2] Sent 19:53:50
19:53:51 Begin echo Two && sleep 3
Two
bash(12037)───moonie(16150)─┬─moonie(16155)───sleep(16157)
├─moonie(16159)───sleep(16161)
└─pstree(16162)
19:53:54 Ended echo Two && sleep 3
19:53:54 Read Tick [4] Sent 19:53:54
19:53:54 Begin echo Three && sleep 6
Three
bash(12037)───moonie(16150)─┬─moonie(16155)───sleep(16157)
├─moonie(16164)───sleep(16166)
└─pstree(16167)
19:53:59 Ended echo One && sleep 8
19:53:59 Read Tick [3] Sent 19:53:59
19:53:59 Begin echo Four && sleep 5
Four
bash(12037)───moonie(16150)─┬─moonie(16164)───sleep(16166)
├─moonie(16168)───sleep(16170)
└─pstree(16171)
19:54:00 Ended echo Three && sleep 6
19:54:00 Read Tick [5] Sent 19:54:00
19:54:00 Begin echo Five && sleep 9
Five
bash(12037)───moonie(16150)─┬─moonie(16168)───sleep(16170)
├─moonie(16172)───sleep(16174)
└─pstree(16175)
19:54:04 Ended echo Four && sleep 5
19:54:09 Ended echo Five && sleep 9
19:54:09 Discard Tick [6] Sent 19:54:04
19:54:09 Discard Tick [7] Sent 19:54:09
================= done ====================