I am creating a command line tool.
In this tool, I want to add a command line option to set the number of threads.
At the moment, I have something like this in mind.
First, add add_worker
and remove_worker
to Crystal::Scheduler
.
class Crystal::Scheduler
def self.add_worker
pending = Atomic(Int32).new(1)
th = Thread.new do
scheduler = Thread.current.scheduler
pending.sub(1)
scheduler.run_loop
end
@@workers.not_nil! << th
while pending.get > 0
Fiber.yield
end
end
def self.remove_worker
return if @@workers.not_nil!.size <= 1
@@workers.not_nil!.pop
end
end
Next, write a option parser.
on("-t", "--threads INT", "Number of threads [4]") { |v| set_threads(v.to_i) }
private def set_threads(n)
if n > 4
(n - 4).times { Crystal::Scheduler.add_worker }
elsif n < 4 && n > 0
(4 - n).times { Crystal::Scheduler.remove_worker }
else
Utils.print_error!("Invalid number of threads: #{n}")
end
end
This somehow works (or appears to work) But not reliable.
How would you implement this feature?
@@workers is generated here
It may be easy to avoid assigning jobs to some workers, but that will not increase the number of workers.
I know it is dangerous to change the number of working members during execution, I want to set it only once when I start the command (in options, not in environment variables).