# \[SOLUTION\] Process Rings (#135)

**URL:** <https://www.ruby-forum.com/t/solution-process-rings-135/112561>\
**Category:** Ruby\
**Created:** [August 20, 2007, 11:12pm UTC](https://www.ruby-forum.com/t/solution-process-rings-135/112561 "2007-08-20T23:12:27Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![jameskelly](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3ab097/32.png) [@jameskelly](https://www.ruby-forum.com/u/jameskelly)\
**Post date:** [August 20, 2007, 11:12pm UTC](https://www.ruby-forum.com/t/solution-process-rings-135/112561/1 "2007-08-20T23:12:27Z")

</div>

Here’s my solution. Its “processes” are just plain threads. It works  
pretty well, but it hangs on rings of size 1.

$processes = []

def kill\_processes  
$processes.each do |thr|  
thr.exit!  
end  
end

thread\_proc = proc do  
Thread.stop  
if Thread.current[:count] == 0  
Thread.current[:next] = $processes.first  
else  
Thread.current[:next] = Thread.new(&thread\_proc)  
Thread.current[:next][:count] = Thread.current[:count] - 1  
$processes.push(Thread.current[:next])  
true until Thread.current[:next].stop?  
Thread.current[:next].run  
end  
while true  
Thread.stop  
msg = Thread.current[:message]  
cnt = Thread.current[:message\_count]

```
Thread.current[:message] = nil
Thread.current[:message_count] = nil

if cnt == 0
  kill_processes
else
  Thread.current[:next][:message_count] = cnt - 1
  Thread.current[:next][:message] = msg
  #On small rings, the message can circle around before the first 

```

thread has stopped  
true until Thread.current[:next].stop?  
Thread.current[:next].run  
end  
end  
end

processes, cycles = ARGV.map{|n| n.chomp.to\_i}

$processes.push(Thread.new(&thread\_proc))  
true until $processes.first.stop?  
$processes.first[:count] = processes - 1  
$processes.first.run

puts “Creating #{processes} processes…”  
sleep(0.1) until $processes.length == processes

puts “Timer started.”  
start\_time = Time.new

puts “Sending a message around the ring #{cycles} times…”  
$processes.first[:message\_count] = processes \* cycles  
$processes.first[:message] = “Good day!”  
$processes.first.run

sleep(0.1) while $processes.first.alive?

puts “Done.”  
puts "Time in seconds: " + (Time.new.to\_i - start\_time.to\_i).to\_s

----- Original Message ----  
From: Ruby Q. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
To: ruby-talk ML [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
Sent: Friday, August 17, 2007 8:15:37 AM  
Subject: [QUIZ] Process Rings (#135)

The three rules of Ruby Q.:

1. Please do not post any solutions or spoiler discussion for this quiz  
until  
48 hours have passed from the time on this message.

2. Support Ruby Q. by submitting ideas as often as you can:

[http://www.rubyquiz.com/](http://www.rubyquiz.com/)

1. Enjoy!

Suggestion: A [QUIZ] in the subject of emails about the problem helps  
everyone  
on Ruby T. follow the discussion. Please reply to the original quiz  
message,  
if you can.

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

I recently wrote about a challenge in the Programming Erlang book on my  
blog:

```
http://blog.grayproductions.net/articles/2007/08/13/erlang-message-passing

```

Language comparison issues aside, just figuring out how to build a ring  
of  
“processes” was quite the brain bender for me. That always makes for  
good Ruby  
Quiz material, in my opinion.

The task is straight forward:

```
1. Your program should take two command-line arguments: a number of
   processes and a number of cycles.
2. Begin by creating the requested number of processes, in a ring.
   For example, when three processes are requested, process one
   creates and sends messages to process two, which creates and 

```

sends  
messages to process three. The third process then sends its  
messages back to process one.  
3. Pass a message around your ring of processes a number of times  
equal to the requested cycles. Print timing results for how  
long this takes.

The message you pass doesn’t much matter. A simple String is fine. You  
may  
also wish to pass a counter with it, to verify the correct number of  
sends.

I’ll leave the definition of “processes” intentionally vague. Ruby  
doesn’t have  
an equivalent to Erlang processes so we will just say that each process  
should  
represent a node where we could run some instructions concurrently. Be  
creative.
