Tmux is a client server architecture. Whenever you create a new session/windows/pane, the server allocates a new external virtual/terminal to that element just like is has been manually started from elsewhere. This means that each tmux has its own stdin/stdout that notwithstandign you started each session with a popen call have nothing to do with the endpoints of the pipe. Those endpoint are uniquely related to the "tmux client" whose command is consumed immediately.
Nonetheless, you may: 1) send key-sequences to the windows/panes you created through the send-key comamand; 2) collect and receive output from "manually started" (with send-keys) panes-processes using sort of handmade IPC (named pipes, tcpip,...).
Remember that being children-process of different virtual-terminals, each pane/windows will run a different process whose code can be a clone of your program or a second external program. There is no way to have a multhtreaded program handling many tmux-items unless you do not write a dumb I/O hub-tranceiver process for each of them. Otherwise if you want to use a single multi-threaded process and simply need to split the screen in parts, curses library has windows that may serve your scope.