【问题标题】:Is it possible to run two loops at the same time?是否可以同时运行两个循环?
【发布时间】:2012-11-19 20:28:27
【问题描述】:

所以我在网络安全课上有一个项目来制作一个 bash 游戏。我喜欢制作一款中世纪的游戏,你可以在其中建造农场和矿山来获取资源。嗯,我喜欢做这样的东西。为此,我必须运行两个 while 循环。像这样

while [ blah ]; do

    blah

done

while [ blah ]; do

    blah    

done

是否可以同时运行两个while循环,如果我写错了怎么写?

【问题讨论】:

  • “是,不,也许”如何抓住你的答案?很大程度上取决于您计划让这两个循环做什么,以及它们将如何相互通信。您可以嵌套循环,但这可能不是您所追求的。您可以在后台运行两个能够同时运行的进程;您必须知道它们将如何相互通信,并且顶级进程需要在它们运行时做一些事情(或者几乎什么都不做,只是闲逛)。这两个进程的 IPC 将是您的主要问题;他们如何交流?

标签: bash shell


【解决方案1】:

是的,但是您必须为要在其中执行的每个 while 循环创建一个新进程。从技术上讲,它们不会同时运行(除非您考虑多个内核,但这甚至不可靠) .

以下是如何使用 bash 分叉多个进程的链接。

Forking / Multi-Threaded Processes | Bash

既然你提到这是一个学校项目,我就停在这里,以免我帮你“不学”。

R

【讨论】:

  • 我不太明白这个分叉的东西是什么,我不明白使用它会发生什么。
  • 在 Unix 上,fork() 是用于创建除第一个进程之外的每个新进程的系统调用。您的 shell 每次运行新命令时都会使用 fork()(除非您使用 exec 调用新命令)。当您在后台运行带有& 的shell 脚本时,它使用fork();在fork() 之后,子进程继续进行后台工作,而父shell 继续进行下一项工作。 fork() 系统调用为您提供原始进程的两个几乎相同的副本;主要区别在于子进程ID(PID)不同,它知道是子进程。
  • 我想你会从在项目中实现 fork 获得一些荣誉,因为它可能没有被假设或建议,因此看起来有点巧妙(或者看起来像你在网上问的那样,呵呵)
【解决方案2】:

你也可以使用嵌套的 for 循环

for (( i = 1; i <= 5; i++ ))      ### Outer for loop ###
do

    for (( j = 1 ; j <= 5; j++ )) ### Inner for loop ###
    do
         echo -n "$i "
    done

    echo "" #### print the new line ###

done

编辑:我以为您的意思是嵌套循环,但再次阅读您说“同时”运行两个循环。不过我会在这里留下我的答案。

【讨论】:

  • 我不认为这就是 OP 所说的“同时”。
【解决方案3】:

如果您在每个 done 之后放置一个 &amp;,例如 done&amp;,您将在后台创建运行 while 循环的新进程。但是,您必须小心意识到这意味着什么,因为 bash 脚本将在创建这些新进程后继续执行命令,即使它们尚未完成。您可以使用wait 命令来防止这种情况发生,但我不太习惯使用它,所以我无法保证。

【讨论】:

  • 谢谢你,我会开始测试它,看看它是如何工作的。你知道我如何使用等待的任何信息吗?
  • 使用wait 很简单;您在脚本中单独编写 wait 作为命令。在脚本启动的所有子进程完成之前,脚本不会继续执行下一个命令(wait 之后)。
  • 嘿,它也会像这样吗。
  • 这就像您在之前的评论中提出的那样。 while condition; do COMMANDS; done &amp; while other_condition; do OTHER_COMMANDS; done &amp; wait,基本上。这里最重要的部分是并发,以及所有相关内容。如果您走这条路线,那可能是您关注的重要部分。否则,我建议您创建一个大型主程序循环,只处理游戏循环中每个步骤需要完成的不同事情,而不是让多个循环同时运行
  • 这取决于你的脚本。如果在while 循环之后还有其他命令,而您不想在循环完成之前运行,那么您需要使用wait。如果在循环结束之前没有其他不应运行的命令,则不需要wait
【解决方案4】:

首先,将循环包装成一个函数,然后 fork 它。 这是在您想要拆分进程时完成的,例如,如果我正在处理具有 160,000 多行的 CSV,则单个进程/“线程”将需要数小时。如果您将循环包装到一个函数中并简单地 fork 它,您将运行 x 数量的进程,然后添加 wait/kill defunct 进程循环,您就完成了。你在看什么。

带有嵌套循环的while循环:

   function jobA() { 
       while read STR;
        do
            touch $1_temp
               key=$(IFS="|";set -- $STR; echo $1)                  
                for each in ${blah[@]};
                    do
                        #echo "$each"

                    done

        done <$1;
    }


  for i in ${blah[@]};  
            do 
            echo "$i"

            $(jobRDtemp $i) &

            child_pid=$!
            parent_pid=$$
            PIDS+=($child_pid)

            echo "forked process $child_pid with parent $parent_pid"
        done

            for pid in ${PIDS[@]};
                do
                    wait $pid
                done
                    echo "all jobs done"
                    sleep 1

现在包装好了,这里是一个 FORKED 循环的例子。这意味着您将在后台运行并行进程,WAIT 将等待 ALL 完成后再继续。这对于某些类型的脚本很重要。

另外,不要使用上面介绍的 C 风格编写的嵌套 FOR 循环,例如:

for (( i = 1; i <= 5; i++ ))      ### Outer for loop ###

这非常慢。使用这种类型:

for each in ${blah[@]};
                    do
                        #echo "$each"
                            if [ "$key" = "$each" ]; then
                                # echo  "less than $keyValNeed..."
                                echo $STR >> $1_temp
                            fi 
                    done

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多