Bash shell:分配全局变量时的竞争条件
我正在编写一个脚本:Bash shell:分配全局变量时的竞争条件,bash,shell,sh,race-condition,Bash,Shell,Sh,Race Condition,我正在编写一个脚本: #script_1.sh function a() { export var1='...some calculations on $@...'; } function b() { a "$@" local loc_b=$var1 } function c() { a "$@" local loc_c=$var1 } #script_2.sh source script_1.sh b val1 & c val2 &
#script_1.sh
function a() {
export var1='...some calculations on $@...';
}
function b() {
a "$@"
local loc_b=$var1
}
function c() {
a "$@"
local loc_c=$var1
}
#script_2.sh
source script_1.sh
b val1 &
c val2 &
b val2 &
函数a
具有getopt
命令,并解析b
和c
的参数。这在很大程度上得到了简化
当我在最后再次调用函数b
、函数c
和函数b
作为后台进程时,我担心在将导出的var1变量
分配给局部变量时可能会遇到竞争条件
函数b
或函数c
的调用将作为后台进程,那么我需要担心这里的竞争条件吗每个后台进程都有自己的环境副本。子进程无法更改其父进程的环境。因此,不存在争用条件:如果在运行后台进程之前更改全局变量,进程将复制新值。如果在更改值之前运行后台进程,该进程将看到旧值
#!/bin/bash
global=1
inc () {
((++global))
echo inc: $global
}
dec () {
((--global))
echo dec: $global
}
inc & dec &
# 2 0
global=10
inc & dec & inc & dec &
# 11 9 11 9
每个后台进程都有自己的环境副本。子进程无法更改其父进程的环境。因此,不存在争用条件:如果在运行后台进程之前更改全局变量,进程将复制新值。如果在更改值之前运行后台进程,该进程将看到旧值
#!/bin/bash
global=1
inc () {
((++global))
echo inc: $global
}
dec () {
((--global))
echo dec: $global
}
inc & dec &
# 2 0
global=10
inc & dec & inc & dec &
# 11 9 11 9
导出
在这里不做任何有价值的事情:您只能将值导出给您的孩子,而不能导出给您的父母或兄弟姐妹。(一个导出一个值然后退出的子shell,然后简单地将该值扔掉)。很容易将其标记为的副本,因为该问题及其答案中传达的信息在这里有争议/传达了所有相关信息。非常好的分享。我混淆了环境
、子shell
和全局
的概念。如果这是错误的,请纠正我:1。对于函数a
调用函数b
,我们不需要使用导出
,因为这将是相同的过程。2. <代码>在后台调用的函数a将继承其父函数的环境(包括导出到函数调用的所有变量)。(1)和(2)都正确。(您甚至不必总是为孩子们使用export
——真正的子shell是一个fork()
,没有execve()
,但如果您需要它在exec
-家族调用中生存,您只需要导出一个变量将其放入环境中).export
在这里不做任何有价值的事情:您只能将值导出给您的孩子,而不能导出给您的父母或兄弟姐妹。(一个导出一个值然后退出的子shell,然后简单地将该值扔掉)。很容易将其标记为的副本,因为该问题及其答案中传达的信息在这里有争议/传达了所有相关信息。非常好的分享。我混淆了环境
、子shell
和全局
的概念。如果这是错误的,请纠正我:1。对于函数a
调用函数b
,我们不需要使用导出
,因为这将是相同的过程。2. <代码>在后台调用的函数a将继承其父函数的环境(包括导出到函数调用的所有变量)。(1)和(2)都正确。(对于孩子们,你甚至不总是需要export
——一个真正的子shell是一个fork()
,没有execve()
,但是如果你需要它在exec
-家族调用中生存,你只需要导出一个变量将它放入环境中)。明白了,这很有帮助。谢谢:)明白了,这很有帮助。谢谢:)