Multithreading is hard, but it's not impossible. You do need to think of your game slightly differently in terms of data and processes. I like to do things with events, commands, and worker threads. I don't have any mutexes or locks in my system, but I do design my data structures so that they are contention free for the duration of the worker thread's processing. I use lockless queues to pass events/messages between threads (typically updates from my entity system to the main thread for dispatching later in the frame/next frame).
The result of one unit's update might depend on another, so this isn't a solution for lockstep multiplayer games.
I've run into that before, what I've done is maintain several buckets of entities to update based on a parent. I've never really got further than 4 or 5 deep. I then update all the entities in bucket 1 (since they don't depend on each other or a parent), then 2 (their parents are all up to date), etc, etc. This requires a little extra book keeping, but definitely possible.
Sending them off to the GPU in each worker thread? They share the same GL context and would have to constantly switch with wglMakeCurrent. Plus what if they require different shaders?
You don't have to actually call any GL commands from the worker threads, just get everything ready to draw (cull and uniform setup). If you're doing some cool multidraw-indirect stuff, you can have each thread touch the command buffer, but that requires some rather specialized data structures and beyond what I know about. In my rendering engine, I've encapsulated rendering of objects into a command class. Worker threads generate all the command classes in parallel (each renderable object generally caches and reuses it's render commands). The command classes get their uniform data updated (not calling glUniform, just holding the vector/matrix ready to call glUniform). When the worker threads are all done, I then combine each worker threads command list, sort by render state and then process the entire list calling exec on each command. This is where the GL calls are actually made. You could even push the entire sorted command list into a separate thread just for rendering.
Cheers,
Bob