2017-10-13 168 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