मैं विकास में एक कार्यक्रम के लिए परीक्षण इनपुट चलाने के लिए समानांतर जीएनयू का उपयोग करता हूं। सरलीकृत सेटअप:

find . -iname '*test*' | parallel -k -I@ echo running '@' \; my_binary \; echo '@': exited with \$?

यदि my_binary अनंत लूप में फंस जाता है, तो मैं Ctrl+C -> इस परीक्षण स्क्रिप्ट को सिगिनट करता हूं।

यहां, दुर्भाग्य से, समानांतर सभी (पहले से मुद्रित, लेकिन ऑर्डर करने के लिए बफ़र किया गया) स्टडआउट खाता है, इसलिए मैं नहीं देख सकता कि कौन सा परीक्षण अटक गया।

मैं यह स्टडआउट प्राप्त करना चाहता हूं, लेकिन मुझे ऐसा विकल्प नहीं मिला जो मैन पेज में करता हो। क्या आपके पास यह कैसे करना है इस पर विचार हैं?

  • मैं आउटपुट का क्रम रखना चाहता हूं (यहां -k के कारण), इसलिए बस सभी आउटपुट को सीधे फ़ाइल में रीडायरेक्ट करने से काम नहीं चलेगा (जब तक कि एक चाल है जिसके बारे में मुझे जानकारी नहीं है?)

  • प्रत्येक परीक्षण के लिए किसी प्रकार का टाइमआउट सेट करना अव्यावहारिक है

    (कुछ परीक्षणों में बहुत लंबा समय लगता है, लेकिन आप जानते हैं कि एक समस्या बहुत अच्छी है सीपीयू उपयोग आदि के कारण जल्दी)।

  • मुझे वास्तव में ग्नू-समानांतर का उपयोग करने की परवाह नहीं है, कोई समाधान बहुत अच्छा होगा।

1
ChrisB 20 अगस्त 2021, 21:56

2 जवाब

सबसे बढ़िया उत्तर

ठीक है, मैंने इसे स्वयं समझ लिया।

समानांतर में एक --joblog विकल्प है जो सभी तैयार नौकरियों को तुरंत प्रिंट करता है, लेकिन केवल सबमिशन के क्रम में!

यह वही है जो हम चाहते हैं, निम्नलिखित अवधारणा के प्रमाण के लिए @Mark Setchell से टैग विचार के संयोजन में:


output="$(mktemp)" # parallel will put the line buffered command output here
joblog="$(mktemp)" # parallel will output it's joblog here for sigint recovery

function run_test () {
   tag="$1"
   input="$2"
   echo "$tag: started $input"
   # simulate doing work for demonstration
   sleep "$tag"
   # output from the test must have the tag prepended to each line 
   echo "$input: test output"  2>&1 | sed "s/^/$tag: /" 
   echo "$tag: finished $input, exited with $?"
}

function handle_sigint () {
    echo " interrupted!"
    # check for finished jobs (tag in the joblog)
    awk '(NR>1){printf "^%s: \n", $1}' "$joblog"  | 
        # remove all output lines with tags from finished jobs
        grep -v -f - "$output" | 
        # print the remaining output lines, sorted by tag, but in order of line submission
        sort -snk1 |
        # but strip away the tag from the beginning of the line
        cut -d" " -f2-
    rm "$output"
    rm "$joblog"
    exit 0
}

export -f run_test
trap handle_sigint INT

# create some dummy jobs for demonstration
printf "foo\nbar\nbaz\nquux\n" | 
    # create command to run for each test
    awk '{printf "run_test %i %s\n", NR, $1}' | 
    # run the jobs, putting line buffered output into $output and the joblog into $joblog
    parallel --line-buffered --joblog "$joblog" bash -c  &>"$output" & 
# immedeately pipe new joblog lines along until parallel dies or we sigint
tail -f "$joblog" --pid $! |
    # whenever a job is finished --> a joblog line is added, print all lines with that tag from the output
    awk "(NR>1){c=sprintf(\"sed -n 's/^%s: //p' '%s'\\n\" , \$1, \"$output\"); system(c)}" 

# remove the temp files (if we were not interrupted, otherwise handle_sigint does this)
rm "$output" 
rm "$joblog"

1
ChrisB 20 अगस्त 2021, 23:15

जीएनयू समानांतर पूछने के बारे में कि वर्तमान में कौन सी नौकरियां चल रही हैं:

seq 1000 | parallel sleep &
pid=$!
sleep 10
kill -SIGUSR1 $pid
1
Ole Tange 23 अगस्त 2021, 21:25