I spent a few days trying various things including Thread::Pool which although the workers were shown to finish and get removed from the pool the memory usage continued to grow with every copy job. A $pool->join statement crashed the app just like any other thread join.
I ended up going with the separate script which handles the threads and copies. It works great! Now I just need to finish getting the IPC::Open2 stuff working so I can retrieve the success/failure results back from the copy processes, umount the drives, notify the user, etc.
It's sooo nice to finally move past this problem and close in on getting the application completed.
Thanks for all the suggestions and help everyone!