Is it just a matter of buffering where the "foo" really is being printed 1 second before the "\n" and you're just not seeing it flushed? i.e., try putting $|=1 in your script and seeing if you get teh expected 2s-foo-1s-\n behavior.
side comment -- I'm not too familiar with timings/accuracies of sleep, but Time::Hires might be more accurate if exactly 1 second (or 2 or 3) is crucial to your application.