The solution proposed the sage
BrowserUk looks good, but you can see that it's not entirely trivial to declare inner subhashes as shared. Moreover, the solution will be only become more and more complex the deeper your structure gets.
Maybe you can solve your problem by simplifying the specification ? Use Thread::Queue (it works great with "threads") to pass data between threads. On the receiving side, first shove the data into the hash and then print/process it.
This way, you also don't expose the internal representation of the processing thread to the receiving thread, thus keeping the interface cleaner and more flexible.