在bash脚本中多线程独立if语句的正确方法是什么?是否最好放置&代码包含在if或者表达式之后?
对于&在表达式之后,如果if包含大块代码,则根据需要继续进行线程化是有意义的.但是,如果一行代码也以&?结尾
表达后:
if [ expression ] & then #task fi
完成任务后:
if [ expression ] then #task & fi
想象一下,如果所有执行任务的语句彼此独立,那么执行如何与&?的不同位置一起工作根据我的理解,如果放在表达式之后,所有3个表达式(基本上)同时启动,3个任务也是如此.
#Thread 1 #Thread 2 #Thread 3 if [ expr1 ] & if [ expr2 ] & if [ expr3 ] & then then then task1 task2 task3 fi fi fi wait
如果放在任务代码之后,则第一个if将被评估,并且仅在第一个任务开始时才会评估第二个任务.这些任务比同步更加错开.
#Thread 1 #Thread 2 #Thread 3 if [ expr1 ] then task1 & if [ expr2 ] fi then task2 & if [ expr3 ] fi then task3 & fi wait
这些表达式不能组合在一起进行线程化,如下所示:
if [ combined expression ] then #task1 & #task2 & #task3 & fi
解决方法
如果你希望每个if条件在它各自的“线程”(实际上是子shell进程)的上下文中执行,那么我认为要做的事情是把&在每个if的结束fi声明之后.然后,每个if表达式的评估以及条件代码将完全在其自己的“线程”的上下文中发生.
例如:
#/bin/bash if [ 1 ] then for i1 in {1..3}; do echo $i1; sleep 1; done fi & if [ 1 ] then for i2 in {a..c}; do echo $i2; sleep 1; done fi & wait
每个“线程”的输出按预期交错:
1 a 2 b 3 c
注意在&所有情况下,这些实际上是进程(使用fork()创建)而不是线程(使用pthread_create()创建).请参阅Multithreading in Bash.您可以通过创建变量来测试此变量,例如在“线程”启动之前n = 0.然后在一个线程中增加n并在所有线程中回显$n.您将看到每个“线程”获得自己的n – n副本将在递增和非递增线程中具有不同的值. fork()创建一个新的流程副本(包括变量的独立副本); pthread_create()没有.