Sometimes hitting control-c doesn't work: the loop body gets the control-c and the loop keeps iterating. (Although I can't reproduce this behaviour right now with
sleep 1 as the loop condition or the body, I remember seeing it.)
control-z can stop this, and the loop won't resume after
fg unless the loop was inside a subshell like
(while true;do : ;done). (With
bash on GNU/Linux).
Or control-z /
fg is useful if you want the currently-running iteration of the loop to finish cleanly, but not start another iteration.
(Control-z stops a job, getting the kernel to deliver SIGTSTP exactly like how control-c delivers SIGINT, on a TTY that's not in raw mode. The default action for this signal is to stop the job.
bg are job-control commands, see the bash built-in "help" for them and the