Note that a process that requires user input (for example) stops when the input is required, until it's given. In a foreground process you see it's asking for something (or should see if it's sanely programmed), but if it's a background process, it just sits there waiting and won't give a signal unless it's either specifically designed to do so, or you've done something to "watch it". That means the background process that you expect to run in the background for itself, maybe taking a long time, can stop because it wants user input and you wouldn't know it - then when you think it's finished (and are happy because you didn't have to wait it for that long, but were able to do other things) you notice that it hasn't got farther than the beginning because it didn't get it's input
So whenever you run processes in the background, make sure they're actually running and not waiting for something like your input..
To find out the state of a process you can use the 'ps' command, for example. The 'jobs' command displays information about jobs you started in that terminal, 'ps' about all processes (depending on the switches used).
In addition to 'fg' there is 'bg'.
Note that both foreground and background processes usually end when their parent process ends, for example when you close a remote shell connection or close the terminal you were using. Usually if you have processes running in the background and type 'exit' to exit, (at least in some shells) you are warned that there are still jobs running (another 'exit' exits nevertheless, but you have the option to end the processes by other means before exiting). To have the processes run even after you close their parent process (log out, for example), you must use a special method of starting the process, for example nohup. With remote connections (when people remotely login, then start a process and want it to keep running after they close the remote connection) a commonly used method is to run the desired program with 'screen' ('screen programname'). Then the program seems to run normally (but it's actually running on screen), and when you want to exit, you can press CTRL+A, then D, to detach ("put the process in the back", make it disappear from the foreground but still have it run there on 'screen'), and just exit - and the process still runs. Later when you come back (maybe re-login remotely) you can run 'screen -d -r' which re-attaches (and possibly de-attaches the process first, if needed) to the process and you get it back to your screen. Typically people run irc clients on remote machines this way, and have the client running even when they're away.