【问题标题】:shell: race condition in assigning global variableshell:分配全局变量时的竞争条件
【发布时间】:2019-03-03 21:13:05
【问题描述】:

我正在编写一个脚本:

#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 &

function a 具有getopt 命令并解析bc 的参数。这在很大程度上被简化了。

当我最后再次调用function bfunction cfunction b 作为后台进程时,我担心我可能会在将exported var1 variable 分配给局部变量时遇到竞争条件。

  1. 如果我可以保证对function bfunction c 的调用将作为后台进程,我是否需要担心这里的竞争条件?

  2. 如果没有比赛,我可以通过不为每个函数声明局部变量来逃避吗?

【问题讨论】:

  • export 在这里没有做任何有价值的事情:您只能将值导出给您的孩子,而不是您的父母或兄弟姐妹。 (导出一个值然后退出的子shell,然后简单地将那个值扔掉)。
  • 很容易将其标记为 bash background process modify global variable 的重复项,因为该问题中传达的信息及其答案在此处讨论/传达了所有相关内容。
  • 很棒的分享。我对environmentsubshellglobals 的概念感到困惑。如果这是错误的,请纠正我: 1. 对于function a 调用function b,我们不需要使用export,因为这将是相同的过程。 2. 后台调用function a 将继承其父环境(包括导出到函数调用的所有变量)。
  • (1)和(2)都是正确的。 (你甚至不需要为孩子们​​提供export——一个真正的子shell是一个没有execve()fork(),但如果你需要它生存,你只需要导出一个变量将它放入环境中exec-family 电话)。

标签: bash shell sh race-condition


【解决方案1】:

每个后台进程都有自己的环境副本。子进程不能改变其父进程的环境。因此,不存在竞争条件:如果您在运行后台进程之前更改全局变量,该进程将获得复制的新值。如果您在更改值之前运行后台进程,该进程将看到旧值。

#!/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

【讨论】:

  • 知道了,这很有帮助。谢谢:)
猜你喜欢
  • 1970-01-01
  • 2022-08-18
  • 1970-01-01
  • 2023-03-23
  • 2012-04-29
  • 2019-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多