Ruby:
- Looked into ruby's Queue object
- Saw that the method Queue#pop, which returns the first element and removes it from the queue, is blocking, meaning that it will block its thread if the queue is empty while waiting for a value to return.
- This is great for me, because I was looking for a way to have a thread that could pause itself while waiting for files to download and resume itself once those files are downloaded
- I rewrote my threading test to use the queue object, and it ended up being much more straight-forward and probably more thread safe as well
- In the code marked 1. in the code section I have an excerpt I came up with to utilize Queue#pop. This code is intended to be run in a method in a separate thread, and will either parse items if there are any in the queue or do nothing while waiting for more to be added
- END_PARSE_SYM is a constant value that is added to the queue when another method, Parser#finish, is called. As you can see by the code, this signals that there are no more files for the queue to wait for, and therefore the infinite while loop is exited.
- One choice I made while writing my Parser class was to keep the thread behavior up to the code calling the Parser#parse method, meaning that Parser doesn't actually have any multithreading code.
- Instead, you must call something like what is listed in code excerpt 2. The statement within the { } runs in a separate thread, which is good, because in its current form, this method blocks its thread due to the Queue#pop statement being called on an empty queue within Parser#parse
- A side effect of this is that if you call parser.parse in the main thread, it throws a deadlock exception, because the @queue.pop statement is now blocking the main thread, so nothing will ever happen. I think this is acceptable behavior though, because Parser#parse really should never be called in the main thread anyway.
- I will look into other ways to throw an exception if Parser#parse is being called in the main thread
Code:
1.
def parse
...
while true do
puts "Waiting for queue" if @queue.empty?
file = @queue.pop
break if file == END_PARSE_SYM
<... parse code here >
end
end
2.
thread = Thread.new { parser.parse }