ignore_user_abort should make it keep going. What you could do, if you want them to see a message without waiting for the loop:
<html>
<head>
<title>mailing lots of stuff</title>
<meta http-equiv="refresh" content="20;URL=thanks.html">
</head>
<body>
<?PHP
for ($i =0; $i < sizeof($emails); $i++) {
set_time_limit(0);
ignore_user_abort(TRUE);
mail($to, $subject, $message, $headers);
}
?>
</body>
</html>
If I'm not mistaken, that should load up a blank page (you could put text or something into it, look into ob_flush(), I believe is the function), get the loop started, tell it to ignore user aborts, then redirect them to thanks.html after 20 seconds.