Ruby暂停线程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ruby暂停线程相关的知识,希望对你有一定的参考价值。

在ruby中,是否可能导致线程从另一个并发运行的线程暂停。

下面是我到目前为止编写的代码。我希望用户能够输入'pause thread'和sample500线程来暂停。

#!/usr/bin/env ruby

# Creates a new thread executes the block every intervalSec for durationSec.
def DoEvery(thread, intervalSec, durationSec)
    thread = Thread.new do
        start = Time.now

        timeTakenToComplete = 0
        loopCounter = 0
        while(timeTakenToComplete < durationSec && loopCounter += 1)

            yield

            finish = Time.now

            timeTakenToComplete = finish - start

            sleep(intervalSec*loopCounter - timeTakenToComplete)    
        end
    end
end

# User input loop.
exit = nil
while(!exit)
    userInput = gets
    case userInput
    when "start thread
"
        sample500 = Thread
        beginTime = Time.now
        DoEvery(sample500, 0.5, 30) {File.open('abc', 'a') {|file| file.write("a
")}}
    when "pause thread
"
        sample500.stop
    when "resume thread"
        sample500.run
    when "exit
"
        exit = TRUE
    end
end
答案

将Thread对象作为参数传递给DoEvery函数是没有意义的,因为你立即用Thread.new覆盖它,看看这个修改过的版本:

def DoEvery(intervalSec, durationSec)
    thread = Thread.new do
        start = Time.now
        Thread.current["stop"] = false

        timeTakenToComplete = 0
        loopCounter = 0
        while(timeTakenToComplete < durationSec && loopCounter += 1)
            if Thread.current["stop"]
              Thread.current["stop"] = false
              puts "paused"
              Thread.stop
            end

            yield

            finish = Time.now

            timeTakenToComplete = finish - start

            sleep(intervalSec*loopCounter - timeTakenToComplete)

        end
    end
    thread
end

# User input loop.
exit = nil
while(!exit)
    userInput = gets
    case userInput
    when "start thread
"
        sample500 = DoEvery(0.5, 30) {File.open('abc', 'a') {|file| file.write("a
")} }
    when "pause thread
"
        sample500["stop"] = true
    when "resume thread
"
        sample500.run
    when "exit
"
        exit = TRUE
    end
end

这里DoEvery返回新的线程对象。另请注意,Thread.stop在运行线程内部调用,不能直接阻止另一个线程,因为它不安全。

另一答案

您可能能够更好地完成使用Ruby Fiber对象的尝试,并且可能在运行的系统上实现更高的效率。

Fibers是在Ruby中实现轻量级协同并发的原语。基本上它们是创建可以暂停和恢复的代码块的一种方法,就像线程一样。主要区别在于它们永远不会被抢占,并且调度必须由程序员而不是VM完成。

记住MRI的当前实现Ruby不提供任何并发运行的线程,你能够完成的最好的是green threaded程序,以下是一个很好的例子:

require "fiber"

f1 = Fiber.new { |f2| f2.resume Fiber.current; while true; puts "A"; f2.transfer; end }
f2 = Fiber.new { |f1| f1.transfer; while true; puts "B"; f1.transfer; end }

f1.resume f2 # =>
  # A
  # B 
  # A
  # B
  # .
  # .
  # .

以上是关于Ruby暂停线程的主要内容,如果未能解决你的问题,请参考以下文章

在Ruby中的单词之间暂停时拆分语音音频

将新片段添加到后台堆栈是不是会暂停当前片段?

Mediaplayer在切换片段时没有暂停

在 Activity 内部,如何暂停 for 循环以调用片段,然后在按钮单击片段后恢复循环以重新开始

为啥Android不会暂停视图完全被软键盘挡住的片段?

视频没有在片段 ViewPager 中暂停