Too many questions and lines of code in one post :-)
Locking a Thread::Queue shouldn't be needed, that's what the module does for you.
If you need the dictionary to be fast, there's no other option than to share it or duplicate it. If it could be slow, you can create another worker with its own queues that would update the dictionary and answer queries about its content. Basically, when you use Thread::Queue, you shouldn't need threads::shared at all.