선입 선출 프로세스의 수가 계속해서 증가하고 있습니다.

선입 선출 프로세스의 수가 계속해서 증가하고 있습니다.

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
지금은 댓글을 추가할 수 없습니다. 이 코드는 단순화되었으며 루트 계정을 사용하여 폴더에서 실행합니다.

shfiles.txtSH 파일 경로의 모음입니다.

실행된 파일에는 아래와 같이 perforce 명령이 있습니다.

20210326/archive13.sh

20210326/archive14.sh

p4 archive -D depot -t xxxxx#1 

나는 ps -aux | grep sh현재의 과정을 보는 데 익숙합니다. 그것은 성장하고 끝나고 있습니다.

각 프로세스가 끝나면 두 개의 프로세스가 생성됩니다. 그래서 점점 더 많은 프로세스가 있습니다.

이 문제를 해결한 것 같은데 이유를 모르겠습니다. exec 7<>tmp와 같이 fifo 9 -> 7을 수정합니다. 다른 프로세스에서 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

접근 방식이 흥미로워서 따라해봤습니다.

수행할 작업을 설명하는 진단 스크립트가 있습니다. 특히, 각 틱("실행 허용")에 시퀀스 번호와 시간(예: )을 스탬프 처리하므로 [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.script 이름을 사용해도 괜찮지만 .cmds 파일의 매개변수와 참조는 어려울 수 있습니다. 파일이 어떻게 생겼는지 mv모르기 때문에 스크립트(?)가 실행 후 다른 디렉토리로 이동하는 이유를 이해할 수 없습니다 ..cmds

pstree내 bash 및 외부 스크립트 pid는 일정하고 비동기 서브셸 및 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 ====================

관련 정보