Several tools allow a user to work with or view processes:
*
ps reports the status of one or more processes.
*
pgrep looks through the currently running processes and lists the process IDs, which match the input criteria.
*
pstree displays the tree of running processes.
*
top displays the processes that are using the most CPU resources. The top output is periodically updated.
ps Reports the Process Status
The ps (process status) program provides a snapshot of information for processes currently executing on Linux systems. A variety of command-line options control which processes this program reports and what information it reports about each. For details of all the options and output values, consult the ps man page. The following options are particularly useful when investigating processes:
*
a elects all the processes on a terminal and shows those of other users.
*
e displays information about all processes.
*
f provides a full listing.
*
u selects all processes owned by username.
*
x selects processes without controlling ttys.
To view all the options for ps, you can use the man ps command to view the man page.
The output from the ps au option is displayed in the following columns:
*
USER is the username for the running process.
*
PID is the process ID.
*
%CPU is the CPU utilization.
*
%MEM is the memory utilization.
*
VSZ is the virtual memory size.
*
RSS is the resident set sizethe number of kilobytes of program in memory.
*
TTY specifies which terminal the process was started from.
*
STAT is the process state.
*
START is the start time.
*
TIME is the execution time.
*
COMMAND is the command name.
The process state codes have the following meanings. They are taken from the ps man page:
*
D means uninterruptible sleep (can be waiting on I/O).
*
R means runnable (on the run queue).
*
S means sleeping.
*
T means traced or stopped.
*
W means paging.
*
X means dead.
*
Z means a defunct ("zombie") process.
For BSD formats and when a STAT is displayed, additional symbols can be displayed:
*
W means no resident pages.
*
< means a high-priority process.
*
N means a low-priority task.
*
L means pages locked into memory.
Let's look at the sample program ps-test.c, shown in Listing 6.1. We'll look at this program with the ps command to view the different threads while the program runs. ps-test.c is a multiple-thread program that uses pthread_mutex_lock and pthread_mutex_unlock to serialize dlsym and dlopen calls. Let's define some of the APIs that ps-test.c uses.
Mutex objects are intended to serve as a low-level primitive from which other thread synchronization functions can be built. The mutex object referenced by mutex is locked by calling pthread_mutex_lock(). If the mutex is already locked, the calling thread blocks until the mutex becomes available. This operation returns with the mutex object referenced by mutex in the locked state with the calling thread as its owner. The pthread_mutex_unlock() function releases the mutex object referenced by mutex.
dlopen() makes an executable object file available to the calling program. The dlsysm() function allows a process to obtain the address of a symbol defined within an object made accessible through a dlopen() call.
We'll also change ps-test2.c to remove the pthread_mutex_unlock call to cause the program to hang and then look at the threads with the ps command to verify that the program is hung.
ps-test.c
1 #include <pthread.h>
2 #include <dlfcn.h>
3 #include <dirent.h>
4
5 pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
6 void *
7 lookup_thread (void *handle)
8 {
9 while (1) {
10 pthread_mutex_lock( &mutex1 );
11 dlsym (handle, "main");
12 pthread_mutex_unlock( &mutex1 );
13 }
14
15 return NULL;
16 }
17
18
19 int
20 main (int argc, char **argv)
21 {
22 pthread_t loader;
23 DIR *d;
24 struct dirent *dent;
25 char *so;
26
27 pthread_create (&loader, NULL, lookup_thread, dlopen (NULL,
RTLD_NOW));
28 d = opendir ("/usr/lib");
29 while ((dent = readdir (d))) {
30 so = strstr (dent->d_name, ".so");
31 if (!so || so[3])
32 continue;
33
34 printf ("%s\n", dent->d_name);
35 pthread_mutex_lock( &mutex1 );
36 dlopen (dent->d_name, RTLD_NOW | RTLD_GLOBAL);
37 pthread_mutex_unlock( &mutex1 );
38 }
39
40 printf ("we have finished!\n");
41 return 0;
42 }
Another option with using ps to check if the threads are still in an acceptable state is the -fp option You want to know if the thread's time value increases, and both 28447 and 28449 do this. The thread 28447 time increases from 00:00:04 to 00:00:06. The thread 28449 time increases from 00:00:14 to 00:00:23.
Viewing ps-test threads with ps and the -fp PID option.
The sample program ps-test has multiple threads and uses pthread_mutex_lock and pthread_mutex_unlock to serialize the calls between dlsym and dlopen. The new ps-test2.c has been changed to cause a deadlock by commenting out line 37. The deadlock is caused by not doing a pthread_mutex_unlock after the dlopen. ps-test2, views the state of the three threads with ps
ps-test2.c
1 #include <pthread.h>
2 #include <dlfcn.h>
3 #include <dirent.h>
4
5 pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
6 void *
7 lookup_thread (void *handle)
8 {
9 while (1) {
10 pthread_mutex_lock( &mutex1 );
11 dlsym (handle, "main");
12 pthread_mutex_unlock( &mutex1 );
13 }
14
15 return NULL;
16 }
17
18
19 int
20 main (int argc, char **argv)
21 {
22 pthread_t loader;
23 DIR *d;
24 struct dirent *dent;
25 char *so;
26
27 pthread_create (&loader, NULL, lookup_thread, dlopen (NULL,
RTLD_NOW));
28 d = opendir ("/usr/lib");
29 while ((dent = readdir (d))) {
30 so = strstr (dent->d_name, ".so");
31 if (!so || so[3])
32 continue;
33
34 printf ("%s\n", dent->d_name);
35 pthread_mutex_lock( &mutex1 );
36 dlopen (dent->d_name, RTLD_NOW | RTLD_GLOBAL);
37 // cause a dead lock pthread_mutex_unlock( &mutex1 );
38 }
39
40 printf ("we have finished!\n");
41 return 0;
42 }
Building and Running ps-test2
The building of ps-test2 needs two librariesdl and pthread. Building and running ps-test2 can show output.
The ps-test2 program looks to be hung.
Viewing ps-test2 with the ps -fp PID command.
You can filter the output of the ps command in a few different ways. The first does a sort on the first and second field.
There are two emacs processes. PID 21127 is viewing the namei.c file. PID 21132 is viewing the inode.c file.
The next example shows a deadlock in the JFS file system while running a program called fstest. Most of the file system processes are waiting on txBeginAnon. This is not the normal case. Jon Nelson submitted this problem to the JFS mailing list. With the information provided, we were able to determine why the file system was waiting on txBeginAnon. It turned out we were running out of transaction locks (tlocks). The wchan option is the most interesting option for finding the location of the hang in this case. If this is a kernel address, ps uses /proc/kallsyms to find the nearest symbolic location. In this case PIDs 6595 through 6644 are all waiting on txBeginAnon.
. ps Command Showing a Deadlock in JFS
Included below is the output of:
ps -eo pid,wchan:14,comm | grep -E 'fstest|find'
=====================================
6594 wait fstest
6595 txBeginAnon fstest
6596 txBeginAnon fstest
6597 txBeginAnon fstest
6598 txBeginAnon fstest
6599 txBeginAnon fstest
6600 txBeginAnon fstest
6601 txBeginAnon fstest
6603 txBeginAnon fstest
6604 txBeginAnon fstest
6605 txBeginAnon fstest
6606 txBeginAnon fstest
6607 txBeginAnon fstest
6608 txBeginAnon fstest
6609 txBeginAnon fstest
6610 txBeginAnon fstest
6611 txBeginAnon fstest
6612 txBeginAnon fstest
6613 txBeginAnon fstest
6614 txBeginAnon fstest
6615 txBeginAnon fstest
6616 txBeginAnon fstest
6617 txBeginAnon fstest
6618 txBeginAnon fstest
6619 txBeginAnon fstest
6620 txBeginAnon fstest
6621 txBeginAnon fstest
6622 txBeginAnon fstest
6623 txBeginAnon fstest
6624 txBeginAnon fstest
6625 txBeginAnon fstest
6626 txBeginAnon fstest
6627 txBeginAnon fstest
6628 txBeginAnon fstest
6629 txBeginAnon fstest
6630 txBeginAnon fstest
6631 txLockAlloc fstest
6632 txBeginAnon fstest
6633 txBeginAnon fstest
6634 txBeginAnon fstest
6635 txBeginAnon fstest
6636 txBeginAnon fstest
6637 txBeginAnon fstest
6638 txBeginAnon fstest
6639 txBeginAnon fstest
6640 txBeginAnon fstest
6641 txBeginAnon fstest
6642 txBeginAnon fstest
6643 txBeginAnon fstest
6644 txBeginAnon fstest
6755 - find
The ps Option to Show the Syscall Currently Being Executed
The next ps command shows every process with the PID number, % of CPU, memory size, name, and what syscall the process is currently executing. The output is similar to this:
best@sfb1:~> ps -eo pid,%cpu,vsz,args,wchan
PID %CPU VSZ COMMAND WCHAN
1 0.0 588 init [5] select
2 0.0 0 [ksoftirqd/0] ksoftirqd
3 0.0 0 [events/0] worker_thread
4 0.0 0 [khelper] worker_thread
5 0.0 0 [kblockd/0] worker_thread
25 0.0 0 [pdflush] pdflush
26 0.0 0 [pdflush] pdflush
28 0.0 0 [aio/0] worker_thread
27 0.0 0 [kswapd0] kswapd
29 0.0 0 [jfsIO] jfsIOWait
30 0.0 0 [jfsCommit] jfs_lazycommit
31 0.0 0 [jfsSync] jfs_sync
101 0.0 0 [kseriod] serio_thread
1012 0.0 2500 /bin/bash /sbin/ wait
1015 0.0 1360 logger -t /sbin/ pipe_wait
1057 0.0 2500 /bin/bash /etc/h wait
1058 0.0 1360 logger -t /etc/h pipe_wait
1152 0.0 1412 [hwscand] msgrcv
1382 0.0 1436 /sbin/syslogd -a select
1385 0.0 2232 /sbin/klogd -c 1 syslog
1441 0.0 1420 /sbin/portmap poll
1447 0.0 1588 /sbin/resmgrd poll
1513 0.0 4640 /usr/sbin/sshd - select
5452 0.0 6340 /usr/sbin/cupsd select
5469 0.0 42624 /usr/sbin/nscd wait_for_packet
5525 0.0 2596 /opt/kde3/bin/kd select
5562 0.0 4036 /usr/lib/postfix select
5600 0.0 1980 /usr/sbin/xinetd select
5626 0.0 1396 /usr/sbin/cron nanosleep
How to Start a New Process
One way to start a new process is to use the system call. system executes a shell command. The prototype for the system call is as follows:
int system(const char *string);
uses the system call to start the ps command using the au option.
. test-system.c
1 #include <stdlib.h>
2 #include <stdio.h>
3
4 int main ()
5 {
6 printf("Before ps\n");
7 system("ps au");
8 printf("After ps\n");
9 }
pgrep Lists the Process IDs That Match the Input Criteria
The pgrep utility examines the active processes on the system and reports the process IDs of the processes whose attributes match the criteria specified on the command line.
All the criteria have to match. For example, pgrep -u root httpd lists only the processes that are called httpd and that are owned by root. On the other hand, pgrep -u root,best lists the processes owned by root or best.
pgrep without options and just a process name looks in the process queue to see whether a process by a particular name is running. If it finds the requested process, it returns the process ID. For example, this system has four bash processes running with PIDs of 5280, 5295, 8758, and 11400.
Viewing a system with pgrep.
The command pgrep bash is easy and quick to interpret to see "if bash is running."
pstree Displays a Tree of Processes
pstree shows running processes as a tree. pstree visually merges identical branches by putting them in square brackets and prefixing them with the repetition count. It has several options to select criteria and to change the output style. To view all the options for pstree, you can view the man page using the command man pstree.
top Displays Tasks
top provides a dynamic, rolling display of processes on a running Linux system. It also displays other information about the system's overall health, including load averages and memory utilization.
By no means should this be considered a determinative guide. It's just an outline with some examples.
and as always Thank you for flying Penguin Air