2017-10-13 93 views
1

我想同步/「順序化」同時運行特定shell的多個實例。如何同步不同的shell實例

可選地,參數的子集可以確定進程是否可以立即運行或必須等待。

要明確:

如果我同時運行以下三個命令(在這個例子中schematable選項確定鎖)

loadTable --schema dev --table person --file mydata1.txt 
loadTable --schema dev --table person --file mydata2.txt 
loadTable --schema dev --table enterprise --file mydata3.txt 

我想:

  • 第一個個第三命令可以同時運行
    因爲局部變量是不同的(schematable
  • 所述第二命令必須等待的第一一個
    最終因爲局部變量是相同的(schematable

對我來說2種解決方案:

  • loadTable shell必須自己管理一個等待隊列。
  • 代理外殼必須對其進行管理

我有一些想法,但似乎有點複雜......

感謝您的幫助

回答

0

如果我得到它的權利,你需要這樣做:

loadTable --schema dev --table person --file mydata1.txt & 
loadTable --schema dev --table enterprise --file mydata3.txt & 
wait %1 && loadTable --schema dev --table person --file mydata2.txt & 
wait 

在這種情況下,你將運行命令1和3並行l,然後等待第一個命令完成並運行第二個命令。之後,你等他們所有人完成

+0

感謝您的想法,但我不知道推出的命令 – Indent

1

我做了一個同步函數。

我現在可以簡單地在我的腳本的開頭調用(參數解析後):

synchronize $myTable-$mySchema 

它的工作,但我們也許可以簡化它。

代碼:

function synchronize() { 
    key=${1:-noKey};  
    shell_fullname=$(readlink -f $0) 
    shell_basename=$(basename $shell_fullname)  
    hash=$(echo "${shell_fullname}-${key}" | md5sum | cut -b-32) 
    delay=2 
    pid_file=/tmp/${shell_basename}.${hash}.pid  
    current_pid=$$   

    echo "synchronize$shell_basename($key)" 
    ( 
     # First step : lock file   
     isUnLock=true 
     echo "trying to acquire lock" 
     while $isUnLock 
     do 
      # Wait for lock on file desciptor 200 for 10 seconds 
      flock -x -w $delay 200 && isUnLock=false 
      $isUnLock && echo "Waiting lock for"     
     done 

     # here : isUnLock must normally be false 
     $isUnLock && echo "unable to acquire lock" # not possible for me 
     $isUnLock && exit 255 # bad luck... 
     $isUnLock || echo "lock OK"   

     # Second step : waiting eventual previous process 
     while [ -e ${pid_file} ] && kill -0 `cat $pid_file` > /dev/null 2>&1 
     do 
      echo "Another process already running with process_id $(cat ${pid_file})"   
      sleep $delay 
     done 

     # here : previous shell stop and the current process has lock the pid_file 
     echo $current_pid > ${pid_file} 

     # now we can unlock the pid file and the current shell can be running alone safely 
     # (just fail if somebody delete the pid_file...)   

    ) 200>$pid_file.lock # add suffix, flock seems make empty file after lock... 

} 

key=$1 # construct key using args 
synchronize$key 

ligthest版本

function synchronize() { 
    key=${1:-noKey};  
    shell_fullname=$(readlink -f $0) 
    shell_basename=$(basename $shell_fullname)  
    hash=$(echo "${shell_fullname}-${key}" | md5sum | cut -b-32) 
    delay=10 
    pid_file=/tmp/${shell_basename}.${hash}.pid  
    current_pid=$$   

    echo "synchronize $shell_basename($key) pid_file=$pid_file" 
    ( 
     # First step : lock file, Wait for lock on file desciptor 200 
     echo "trying to acquire lock" 
     flock -x 200 
     echo "lock acquired" 

     # Second step : waiting eventual previous process   
     [ -s $pid_file ] && previous_pid=$(cat $pid_file) || previous_pid=00 # 00 is an impossible pid   
     [ -e /proc/${previous_pid} ] && echo "Another process already running with process_id $previous_pid"   
     while [ -e /proc/${previous_pid} ]; do sleep $delay; done 

     # here : previous shell is stop and the current process has lock the pid_file   
     echo $current_pid > ${pid_file}   
     echo "current pid $current_pid is running" 

     # now we can unlock the pid file and the current shell can be running several minutes  

    ) 200>$pid_file.lock # add suffix, flock seems make empty file after lock... 

} 
1

您可以簡化和securise有點第二步
(securise =>通過這種方式,它的工作原理,即使$pid_file是刪除在上次執行期間)

# Second step : waiting eventual previous process 
previous_pid=$(cat $pid_file) 
previous_pid=${previous_pid:00} # 00 is an impossible pid 
while [ -e /proc/${previous_pid} ] 
do 
    echo "Another process already running with process_id ${previous_pid}"   
    sleep $delay 
done