Slowing threads


#1

Hi!

I have written a program that simulates three “consoles” that accept
keyboard input and run concurrently. You can type commands which each
run at different speeds without interfering with other commands. It
works but it’s complex and I think it can be simpler if I have each
command run in it’s own thread - at the moment I don’t use threads at
all.

So I have been creating threads to test and playing with priorities.
I’d like to be able to control the speed at which processes run but if
I set a thread to just one priority higher than another, it is
scheduled tens of thousands of times more often.

So:

  1. What do the priorities actually mean?
  2. If I have to slow one thread just a little, that means messy
    sleep() commands on every second line. Is there a way I can call just
    parts of a passed-in block?
    ie. can I do something similar to this:

def sleeper(&block)
block.each_command do |c|
eval©
sleep(0.5)
end
end

sleeper do
puts “one”
puts “two”
puts “three”
end

If it’s too much magic I’ll just intersperse with sleep, just thought
there might be a better way.


#2

On May 10, 2006, at 3:48 PM, Leslie V. wrote:

I’d like to be able to control the speed at which processes run but if

   puts "three"

end

If it’s too much magic I’ll just intersperse with sleep, just thought
there might be a better way.

If you really want this much fine grained control over the thread
scheduler it probably means patching ruby itself. OTOH that would
probably be cool.


#3

It’s rarely a good idea to modify the priorities of threads in Unix
systems.
Almost all thread-schedulers will never schedule a thread if there is at
least one runnable thread with a higher priority, which explains the
results
you describe. Your lower-priority threads will basically only get
scheduled
when they’re lucky enough to find the highest-priority thread
non-runnable.
If you mess with priorities, you also face the risk of priority
inversions,
where a high-priority thread requires a resource held by a
lower-priority
thread, and they lock each other.

Keep it simple. Sounds like the semantics of your application is to
simulate
users working at different rates. There’s nothing there that implies a
dependence among the threads. I’d use random sleep intervals.


#4

On 5/10/06, Francis C. removed_email_address@domain.invalid wrote:

users working at different rates. There’s nothing there that implies a
dependence among the threads. I’d use random sleep intervals.

Thanks. I’ll probably have a command put together a list of
“micro-tasks” and “execute” each one with a random sleep afterwards.
Not too bad.

Like so:

def command_ls(processorLoad)
microCommands = [] << makeReadDiskMicroCommands(10)

filesText = getFiles.join("\n")
microCommands = << filesText.makeWritelineMicroCommands

loop do
	doMicroCommand(microCommands.shift)
	sleep(rand(processorLoad))
	break if microCommands.empty?
end

end


#5

On May 11, 2006, at 9:00 AM, Jake McArthur wrote:

  sleep Thread.current.execution_speed
end

}
end

Then, at the beginning of any thread you want slowed down, call the
set_execution_speed method. This will limit the rate that each line
of code in the thread is executed. You can also modify the method
so that it limits based on other criteria such as method calls.

set_trace_proc will make your program run much slower than you expect.


Eric H. - removed_email_address@domain.invalid - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com


#6

Insert the following code somewhere in your main thread:

class Thread
attr_accessor :execution_speed
end

def set_execution_speed(seconds_per_line)
Thread.current.execution_speed = seconds_per_line
set_trace_func proc { |event, file, line, id, binding, classname|
if event == “line” and !Thread.current.execution_speed.nil?
sleep Thread.current.execution_speed
end
}
end

Then, at the beginning of any thread you want slowed down, call the
set_execution_speed method. This will limit the rate that each line
of code in the thread is executed. You can also modify the method so
that it limits based on other criteria such as method calls.

  • Jake McArthur

#7

On 5/11/06, Jake McArthur removed_email_address@domain.invalid wrote:

   sleep Thread.current.execution_speed
 end

}
end

Then, at the beginning of any thread you want slowed down, call the
set_execution_speed method. This will limit the rate that each line
of code in the thread is executed. You can also modify the method so
that it limits based on other criteria such as method calls.

Thanks Jake, this is a very cool idea! Pretty sure it won’t be fast
enough (this is for a game) - but I have been playing with
set_trace_func quite a bit since your post.