On most Unix systems, services are started and stopped by the init system. Many Linux distributions use the legacy sysvinit, which almost completely lacks service management functions, so scripts in
/etc/rc.d perform the actual job of starting or killing Apache. These initscripts are written in plain sh and have no other means of tracking the processes they launch – other than by reading its PID from a preset location. (The initscript can know PIDS only of processes it launched directly, but not of children of those processes, nor processes launched the last time the same script was called. This means that the initscript cannot track processes that were programmed to "daemonize" themselves.)
(Yes, a process can be found using
ps -ef, or by examining
/proc directly. However, this is a somewhat unreliable method – there can be several Apache processes running at the same time: for example, mpm-prefork, or multiple independent Apache configurations. Because of this, almost every daemon on Linux will create a "pidfile" in
/var/run, in order for it to be easily stoppable by an initscript. You'll likely have
sshd.pid, and so on.)
Only very recent Linux init systems bother tracking processes: Upstart in Ubuntu has to be told exactly how many forks to expect, while systemd in Fedora uses the kernel cgroups to track processes belonging to a service.