GNU Parallel

https://www.gnu.org/software/parallel

This has a bit of a learning curve, but gives you more control than xargs -P.

Run copies of a program without any arguments

$ parallel -n0 program program_args ::: {1..10}
$ seq 10 | parallel -n0 program program_args

Run named copies of a program, with labelled output

The "name" is passed as the final argument to the program. I can't find a way to keep names around for --tag without passing them to the program; -n0 appears to print empty tags, unfortunately.

$ parallel --tag program program_args ::: {1..10}
$ seq 10 | parallel --tag program program_args

Enable line-buffering

As far as I can tell, default behavior is to buffer internally and only flush to STDOUT when a program is done. The --lb flag enables line buffering, so a flush occurs on every newline.

Edit