当我完成多线程时该怎么办

时间:2014-02-12 20:00:32

标签: ruby multithreading

我正在用Ruby / Tk编写程序。有一次,我正在执行一项需要一些时间的任务,我想展示一些反馈。我用线程完成了这个。我是这个整个线程的新手,当我完成线程时,我不知道如何回到非线程世界。

让我用一个例子来说明。

legitCreds = true
doneValidate = false

# (A) Thread with time-consuming call
validator = Thread.new do
    # THIS CALL TAKES 5-10 seconds
    legitCreds = checkDoorsCreds(session, ValidateTimeout)

    # indicate when this call is done
    mutex.synchronize do
        doneValidate = true
    end
end

# (B) Thread with GUI feedback for user
timeElapsed = 0
textVisible = false
progress = Thread.new do
    if ! doneValidate
        loop do
            sleep 0.5
            timeElapsed += 0.5

            mutex.synchronize do
                if ValidateTimeout - timeElapsed <= 0 || doneValidate
                    @SI['statMessL'].text = ""
                    Thread.kill(progress)
                end
            end

            if textVisible
                @SI['statMessL'].text = ""
                textVisible = false
            else

                @SI['statMessL'].text = "Timeout in #{(ValidateTimeout - timeElapsed).round} seconds..."
                textVisible = true
            end

        end
    end
end


# (C) Should only run after A and B are done.
if legitCreds
    File.open(PathToUserNames, 'w') { |file| file.write(@SI['unameTB'].get) }
    # Go to next state!
end

所以问题在于,正如上面编码的那样,(C)在完成(A)和(B)之前运行,这是无用的,因为 legitCreds 是由线程A设置的。

我想在(C)

之前加上以下代码
validator.join
progress.join

但这会冻结GUI,我也不想这样做。

我还考虑将(C)的内容放在(A)的末尾(但仍然在验证器线程内。这让我得到了正确的行为,但它似乎错了,因为那时候我的程序的其余部分看起来将在验证器线程中运行。

总之,我希望在(A)和(B)之后运行(C)而不冻结GUI,而(A)和(B)工作。

我该怎么做?

另外,如果你看到任何其他no-nos,请告诉我。正如我所说,我是新手,我想养成良好的习惯。

谢谢,

Grasswistle

1 个答案:

答案 0 :(得分:0)

您写道:

  

我还想过把(C)的内容放在(A)的末尾(但是   仍在验证程序线程内。这让我行为正确,   但它似乎是错误的,因为我的程序的其余部分看起来像它   将在验证程序线程中运行。

我不熟悉Tk,但据我所知的GUI应用程序,你的程序不会从另一个线程开始工作 - (C)只会改变应用程序的状态和GUI事件将继续从GUI线程处理...

所以(C)可以附加到(A)或(B)(关注点的分离可能有利于(B)而不是(A)),并且你的申请应该顺利地继续......