Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash shell:分配全局变量时的竞争条件_Bash_Shell_Sh_Race Condition - Fatal编程技术网

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
    -家族调用中生存,你只需要导出一个变量将它放入环境中)。明白了,这很有帮助。谢谢:)明白了,这很有帮助。谢谢:)