After some research I've figured this out on my own.
My approach above doesn't work fully and is more complicated than needed. The main thing to be aware of is what happens to your database connection when a child exits.
As most developers should know when you fork a process the child gets a copy of everything, including resources like DB connections. However, the tricky part is when a forked child exits it will close those resources. This means the child will close the same DB connection it shared from the parent.
When the child exits the parent will immediately have an invalid DB connection and you'll get an error like "Mysql server has gone away" when you try to do a query in the parent.
One solution to avoid this issue is to make sure the parent always reconnects to the DB right after it forks a child. This means if you fork 100 children your parent is going to have to reconnect 100 times. It's an unavoidable bit of overhead if your children and parent all need to interact with a DB.
So in my code I currently do something like the following right after I fork a child:
$conn = $this->getContainer()->get('doctrine')->getConnection();
$conn->close();
$conn->connect();
If you do a "show processlist" in your mysql client you'll now see multiple connections, one for each forked child.
I've even written a ProcessPool library on github that provides an easy to use API to create lots of worker processes that can return results back to the parent.