Bootstrap

Shell Script—线程

本文主要介绍shell中的线程、线程中的等待和信号;

1.线程

Shell中线程的实现有多种方式,目前只介绍通过&符号;通过在命令末尾加上&符号,可以在后台启动一个进程并立即返回,允许Shell进程继续执行其他命令;

示例

#!/bin/bash

NUM=20

function fun1()
{
	for ((i=0;i<${NUM};i++));do
		echo -n "fun1"   #-n不换行输出
	done
}

function fun2()
{
	for ((i=0;i<${NUM};i++));do
		echo -n "fun2"
	done
}

function fun3()
{
	for ((i=0;i<${NUM};i++));do
		echo -n "fun3"
	done
}

function fun4()
{
	for ((i=0;i<${NUM};i++));do
		echo -n "fun4"
	done
}

#换行
fun1 &
fun2 &
fun3 &
fun4 &

#不换行也可以
#fun1 & fun2 & fun3 & fun4

#sleep 0.001   #等待0.001秒
sleep 1   #等待1秒
echo -e "\n"

输出

fun1fun1fun1fun1fun1fun1fun1fun1fun1fun1fun1fun1fun2fun1fun1fun2fun1fun2fun1fun1fun2fun1fun2fun1fun2fun1fun2fun2fun2fun2fun2fun2fun2fun2fun2fun2fun2fun2fun2fun2fun4fun4fun4fun4fun4fun4fun4fun4fun4fun4fun4fun4fun4fun4fun4fun4fun4fun4fun3fun4fun4fun3fun3fun3fun3fun3fun3fun3fun3fun3fun3fun3fun3fun3fun3fun3fun3fun3fun3fun3

在示例中定义了4个函数,fun1、fun2、fun3和fun4,在每个函数中不换行进行循环打印;

2.等待

在Shell中,可以使用不同的方法来实现等待操作,具体取决于你希望在等待期间执行的任务或条件。

2.1 sleep命令

sleep 命令:sleep 命令可用于暂停Shell脚本的执行一段指定的时间。它使用以下语法:

sleep <duration>

其中 <duration> 可以是具体的时间(以秒为单位),你可以直接指定要暂停的秒数,例如 sleep 5 表示暂停执行 5 秒;

除了秒,sleep 命令还支持在数字后面使用单位来指定其他时间单位,常用的时间单位包括:

  • s:秒(默认单位)
  • m:分钟
  • h:小时
  • d:天

你可以根据需要指定不同单位来实现更精确的时间间隔。以下是示例:

sleep 0.01    # 暂停执行 0.01 秒

sleep 30s    # 暂停执行 30 秒

sleep 2m     # 暂停执行 2 分钟

sleep 1h     # 暂停执行 1 小时

sleep 3d     # 暂停执行 3 天

这样,你就可以使用适当的单位根据需求指定 sleep 命令的时间间隔。

2.2 循环等待

可以使用一个循环来持续检查某个条件,直到条件满足为止。例如:

while [ ! -f /path/to/file ]
do
    sleep 1
done

2.3 信号处理

使用 trap 命令可以指定在接收到指定信号时执行某些命令。你可以使用信号来触发等待操作;

示例

#!/bin/bash

#通过信号来进行线程的等待
trap "continue_script=1" SIGUSR1  # 定义一个自定义信号的处理函数
continue_script=0  # 用于控制脚本是否继续执行

echo "begin"
# 在需要等待的地方检查条件
while [ $continue_script -eq 0 ]
do
        echo "$continue_script"
        sleep 1
done

echo "end"

执行kill -SIGUSR1 2059,其中2059为进程号,可以通过ps -ef | grep *.sh | grep -v grep 进行查看进程号;

输出

begin
0
0
0
0
0
0
end

在示例中定义了一个while循环,循环条件为$continue_script -eq 0,当向SIGUSR1发送信号时,$continue_script 值变为1,终止循环条件;

3.信号

在Shell中,有许多不同的信号,下面列出了一些常见的信号以及它们的含义:

  1. SIGINT(2):由终端发送的中断信号,例如使用Ctrl+C时。
  2. SIGQUIT(3):由终端发送的退出信号,例如使用Ctrl+\时。
  3. SIGKILL(9):无法捕获或忽略的强制终止信号。
  4. SIGTERM(15):默认的终止信号,用于正常终止进程。
  5. SIGHUP(1):终端连接断开的信号,通常用于通知进程重新加载配置文件。
  6. SIGUSR1(10)和 SIGUSR2(12):用户自定义信号,可用于自定义操作。
  7. SIGSTOP(19)和 SIGTSTP(20):用于停止进程的信号,例如使用Ctrl+Z时。
  8. SIGCONT(18):继续执行被停止的进程的信号。
  9. SIGPIPE(13):写入已关闭的管道时触发的信号。
  10. SIGCHLD(17):子进程结束或停止时发送给父进程的信号。

这只是一些常见的信号,不同的操作系统和Shell可能还会有其他信号。你可以使用kill -l命令来查看系统上可用的信号列表及其对应的编号;

使用trap命令来注册信号处理器,自定义在接收到特定信号时要执行的操作;

示例SIGINT

#!/bin/bash

cond=0
function fun()
{
	echo "echo get sigint, will finished!"
	cond=1
}

trap fun SIGINT

while [ ${cond} -eq 0 ];do
	sleep 1
done

执行脚本之后,ctrl+c会触发

输出

echo get sigint, will finished!
;