Understanding Linux Processes

For more on waiting on child processes and using the exec functions, see the next article, How system() works.

Introduction
In Linux and other Unix systems, a process consists of code (usually loaded as read-only memory), data, and memory occupied by said data that has been allocated a process identifier (PID) and that can reference certain memory locations known as “address spaces.” Such POSIX process may contain various programs which, in turn, may be made up of various threads. Allocated PIDs are usually numbered over 2 (the PID 1 is typically reserved for the init process).

Let’s retake that running code normally is loaded as read-only memory to avoid writing over the code. This means that, for example, given any C function, various different processes can call it safely.

The ps Command
Now, let’s take a look at the ps (“process snapshot”) command. The following are probably the most-used options used:

ps -ef (every process, full format)
ps ax    (every process with a status code)

Here’s an excerpt of what ps -ef gave me:

UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 16:22 ?        00:00:00 /sbin/init
patrick   4040  4011  0 17:09 pts/1    00:00:00 vi
patrick   4042  3827  0 17:09 pts/2    00:00:00 bash
patrick   4076  4042  0 17:09 pts/2    00:00:00 ps -ef

UID stands for user ID (remember, Unix systems are multiuser systems), not to be confused with UUID, or “unique ID.” CMD is the command that’s being run. STIME is the system time at which the process started. TIME is the CPU time, that is, the amount of time used by the process to process CPU instructions.

Now, here’s an excerpt of my ps ax output:

  PID TTY      STAT   TIME COMMAND
    1 ?        Ss     0:00 /sbin/init
 4040 pts/1    S+     0:00 vi
 4042 pts/2    Ss     0:00 bash
 4083 pts/2    R+     0:00 ps ax

Notice the Status column. The following are the most common STAT codes displayed by ps:
S    Sleeping (waiting for input)
s    Session leader
R    Running
l    Multithreaded
T    Stopped
D    Waiting for input/output to complete.

Killing (or Terminating) a Process
To kill a process using its PID, use the kill command. To kill one via its command name, use either killall or pkill. For example, let’s kill the running Vi process as shown above. There are two simple ways to do this:

kill 4040
killall vi

Both yield the same result; Vi prints out the following:
Vim: Caught deadly signal TERM

If you want to kill all processes being run by a certain user group, use killall -g [group name]. Be careful when using killall, though. On certain systems, it does just that – kill all processes. However, with pkill, it may kill all processes that have the passed argument as a substring on certain systems.

Using getpid and fork
If you want to be able to mess around with an application’s own process, the most important functions are getpid and fork. The getpid function returns the running PID, and fork duplicates the currently running process as a child process. Both are defined in unistd.h and important types related to processes are defined in sys/types.h .

Here’s an example program that clones itself into a child process for five seconds (written in a serif font, just like Stroustrup recommends it).

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main(int argc, char *argv[])
{
     pid_t child_pid;
     child_pid = fork ();
     printf ("Parent PID: %d\nChild PID:%d\n", (int) getpid(), (int) child_pid);
     sleep (5);
     return 0;
}

Here’s a sample output of the program and its corresponding ps ax entries:

$ ./a.out
Parent PID: 2770
Child PID:0
Parent PID: 2769
Child PID:2770

$ ps ax
  PID TTY      STAT   TIME COMMAND
 2769 pts/0    S+     0:00 ./a.out
 2770 pts/0    S+     0:00 ./a.out

Note how there are two outputs. The first one is the child process’ output and the latter is the parent process’ output.(Remember, in order to have enough time to check the processes’ statuses, add sleep(5); right after the printf call.)

About these ads

6 Responses to Understanding Linux Processes

  1. nice walk through. with a program that shows how fork() can be used by a process to get another instance itself.

    -af

  2. Bob says:

    Do not use killall! On some OSs it kills ALL processes. Just like the name implies.

    Use pkill instead, it does what you want, and does the same thing everywhere.

  3. Alice says:

    Do not use pkill! It does substring matching and and kills ALL process that match the substring.

    Use killall instead, it does what you want.

    Or… maybe… just maybe… pay attention to what type of *nix you’re logged into and use whatever is easiest.

  4. […] Before trying out the following code, make sure you have at least a basic handle on Linux processes. […]

  5. labyrinth says:

    Um… I’m just learning here, but it seems the first output is still the first processes, while the second is the child’s.

    I altered your line to:

    printf (“Parent PID: %d\nCurrent PID: %d\nChild PID:%d\n”, (int) getppid(), (int) getpid, (int) child_pid);

    Notice the extra ‘p’ to get parent PID. It seems clear that the first set of output is from the original process since it shows the originating shell as the parent process, its own PID, then the next sequential PID as the child.

    Then in the next set of output, it shows the previous PID as the parent, then its own PID, then 0 as child since no child was forked from it.

    Anyway, thanks so much for this sample code. It was very helpful to get me started playing around with processes.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: