Linux

如何在 bash shell 腳本中啟動兩個執行緒?

  • June 20, 2014

當我在. machineB_machineC``machineA``machineA

如果文件不在那裡,machineB那麼它肯定應該在那裡,machineC所以我會先嘗試從那裡複製文件machineB,如果它不在那裡,machineB那麼我會嘗試從machineC.

我正在使用 GNU Parallel 庫並行複製文件,它工作正常。目前我正在並行複制兩個文件。

目前,我正在使用 GNU 並行複製PRIMARY_PARTITION文件PRIMARY夾中的文件,一旦完成,然後我使用相同的 GNU 並行複製SECONDARY_PARTITION文件夾中的文件,因此它現在是連續的 wrt和文件夾SECONDARY``PRIMARY``SECONDARY

下面是我的 shell 腳本,一切正常 -

#!/bin/bash

export PRIMARY=/test01/primary
export SECONDARY=/test02/secondary
readonly FILERS_LOCATION=(machineB machineC)
export FILERS_LOCATION_1=${FILERS_LOCATION[0]}
export FILERS_LOCATION_2=${FILERS_LOCATION[1]}
PRIMARY_PARTITION=(550 274 2 546 278) # this will have more file numbers
SECONDARY_PARTITION=(1643 1103 1372 1096 1369) # this will have more file numbers

export dir3=/testing/snapshot/20140103

# delete primary files first and then copy
find "$PRIMARY" -mindepth 1 -delete

do_CopyInPrimary() {
 el=$1
 scp david@$FILERS_LOCATION_1:$dir3/new_weekly_2014_"$el"_200003_5.data $PRIMARY/. || scp david@$FILERS_LOCATION_2:$dir3/new_weekly_2014_"$el"_200003_5.data $PRIMARY/.
}
export -f do_CopyInPrimary
parallel -j 2 do_CopyInPrimary ::: "${PRIMARY_PARTITION[@]}"

# delete secondary files first and then copy
find "$SECONDARY" -mindepth 1 -delete

do_CopyInSecondary() {
 el=$1
 scp david@$FILERS_LOCATION_1:$dir3/new_weekly_2014_"$el"_200003_5.data $SECONDARY/. || scp david@$FILERS_LOCATION_2:$dir3/new_weekly_2014_"$el"_200003_5.data $SECONDARY/.
}
export -f do_CopyInSecondary
parallel -j 2 do_CopyInSecondary ::: "${SECONDARY_PARTITION[@]}"

問題陳述:-

有什麼辦法可以啟動兩個執行緒,一個PRIMARY使用與上面相同的設置複製文件夾中的文件,這意味著它將並行複制兩個文件。第二個執行緒SECONDARY使用與我上面相同的設置複製文件夾中的文件,它還應該同時複製兩個文件嗎?

這意味著他們應該在文件夾PRIMARYSECONDARY文件夾中同時復製文件,而不是在PRIMARY文件夾完成後復製文件SECONDARY夾中的文件。

目前,一旦PRIMARY文件夾文件完成,那麼只有我嘗試複製文件SECONDARY夾中的文件。

簡而言之,我只需要啟動兩個執行緒,一個執行緒就會執行它 -

# delete primary files first and then copy
find "$PRIMARY" -mindepth 1 -delete

do_CopyInPrimary() {
 el=$1
 scp david@$FILERS_LOCATION_1:$dir3/new_weekly_2014_"$el"_200003_5.data $PRIMARY/. || scp david@$FILERS_LOCATION_2:$dir3/new_weekly_2014_"$el"_200003_5.data $PRIMARY/.
}
export -f do_CopyInPrimary
parallel -j 2 do_CopyInPrimary ::: "${PRIMARY_PARTITION[@]}"

第二個執行緒將執行這個 -

# delete secondary files first and then copy
find "$SECONDARY" -mindepth 1 -delete

do_CopyInSecondary() {
 el=$1
 scp david@$FILERS_LOCATION_1:$dir3/new_weekly_2014_"$el"_200003_5.data $SECONDARY/. || scp david@$FILERS_LOCATION_2:$dir3/new_weekly_2014_"$el"_200003_5.data $SECONDARY/.
}
export -f do_CopyInSecondary
parallel -j 2 do_CopyInSecondary ::: "${SECONDARY_PARTITION[@]}"

一旦成功複製所有文件,它應該回顯所有文件都已複製的消息。在 java 中,我知道如何啟動兩個執行緒,每個執行緒都在執行某些任務,但不確定在 bash shell 腳本中這將如何工作?

PRIMARY我的主要任務是同時在文件夾和文件夾中使用 GNU 並行複制兩個文件SECONDARY

這可以在 bash shell 腳本中執行嗎?

顯而易見的是:

parallel -j 2 do_CopyInPrimary ::: "${PRIMARY_PARTITION[@]}" &
parallel -j 2 do_CopyInSecondary ::: "${SECONDARY_PARTITION[@]}" &
wait

但是這樣輔助伺服器不會等待主伺服器完成,也不會檢查主伺服器是否成功。讓我們假設 $ PRIMARY_PARTITION[1] corresponds to $ SECONDARY_PARTITION

$$ 1 $$(因此,如果您無法從 $ PRIMARY_PARTITION[1] you will read it from $ SECONDARY_PARTITION$$ 1 $$- 這也意味著 $ PRIMARY_PARTITION and $ SECONDARY_PARTITION 具有相同數量的元素)。然後你可以調節執行 $ SECONDARY_PARTITION[1] on $ PRIMARY_PARTITION$$ 1 $$.

do_Copy() {
 PRIMARY_PARTITION=(550 274 2 546 278) # this will have more file numbers
 SECONDARY_PARTITION=(1643 1103 1372 1096 1369) # this will have more file numbers
 pel=${PRIMARY_PARTITION[$1]}
 sel=${SECONDARY_PARTITION[$1]}
 do_CopyInPrimary $pel || 
   do_CopyInSecondary $sel || 
   echo Could not copy neither $pel nor $sel
}
export -f do_Copy
# Number of elements in PRIMARY_PARTITION == SECONDARY_PARTITION
seq ${#PRIMARY_PARTITION[@]} | parallel -j 2 do_Copy

這將獲得正確的依賴關係,但它一次只會複製 2 個。有-j4同時執行 4 個初選的風險,所以我們也需要提防這種情況:

do_Copy() {
 PRIMARY_PARTITION=(550 274 2 546 278) # this will have more file numbers
 SECONDARY_PARTITION=(1643 1103 1372 1096 1369) # this will have more file numbers
 pel=${PRIMARY_PARTITION[$1]}
 sel=${SECONDARY_PARTITION[$1]}
 sem -j2 --fg --id primary do_CopyInPrimary $pel || 
   sem -j2 --fg --id secondary do_CopyInSecondary $sel || 
   echo Could not copy neither $pel nor $sel
}
export -f do_Copy
# Number of elements in PRIMARY_PARTITION == SECONDARY_PARTITION
seq ${#PRIMARY_PARTITION[@]} | parallel -j 4 do_Copy

sem將初級數限制為 2,次級數限制為 2。

Bash 不支持執行緒,但它支持後台多處理。也就是說,程序被複製到一個新的程序空間,擁有自己的環境、工作目錄等,所有通信都必須通過正常的 IPC 通道進行。但除此之外,它看起來很像執行緒。

您可以通過“背景化”程式碼塊來做到這一點。像這樣:

#!/bin/bash
{
   echo "Foo"
   sleep 1
   echo "Foo: done"
}&    
echo "Bar"
sleep 1
echo "Bar: done"

輸出

Bar
Foo
**[1 second delay]**
Bar: done
Foo: done

您可以通過將程式碼塊包裝在函式中並將該函式作為後台作業執行來獲得相同的效果。

或者,您可以將程式碼塊包裝在括號中而不是大括號中。括號中的語句顯式(並且始終)在單獨的程序中執行;通常大括號中的語句是分組的,但執行時沒有分叉。使用&後綴在後台執行程式碼會強制該程式碼在單獨的程序中執行。

引用自:https://unix.stackexchange.com/questions/130896