Computer lessons

View a list of processes in Linux. Processes in Linux Example of a simple useless program with fork(2)

The approach to process management in Linux is not so obvious. All processes have limited rights and can influence only limited areas of the system, which eliminates the possibility of overloading the processor if the process does not work correctly, and knowledge of process control commands will allow you to quickly deal with the problematic process and stabilize the operation of the OS.

Process Control Commands

To see a list of running processes, you need to enter the command

Ps-A
As a result of executing this command, a list of running Linux processes will be displayed, indicating the name and PID (personal identifier) ​​and the processor time used.

Entering the same command with the key

Aux
allows you to obtain extended information about processes: PID, RAM and CPU usage, user name that started the process, the command that started the process and operating time.

Using various switches of the ps command, you can get other information about running processes: parent process ID, priority value, status (running, sleeping, swap state, stopped, zombie process), percentage of memory and CPU time, start time and etc.

PS
displays information about the state of processes at the current time. To display information about the list of running Linux processes in real time, use the command

Top
The output of the top command is similar to the output of the ps command, with the difference that the process information is constantly updated.

The process priority value can range from -20 (high) to +20 (low). By default, the launched process is given the priority of the parent process. To change the priority of a running process, use the command

Nice
which specifies how different the priority of the new process should be from the priority of the parent process.

The nice command argument values ​​range from -20 to +19. Team

Renice
changes the priority of running processes: renice -3522 -uuser– increasing priority by 3 for user processes with ID 522.

Setting negative priorities is available only to the superuser.

To suspend, terminate, start a suspended process, as well as to communicate other information to processes, signals are used that are sent to processes using the kill command, for example:

  • kill-9 688 – termination of the process with PID688 in any case (kill signal);
  • kill -15 688 – termination of the process from PID688 programmatically (term signal);
  • kill -19 688 – suspends execution of the process with PID688 (stop signal).
Other options and signals of process control commands can be found by calling help on these commands; sometimes there are differences in them, depending on the distribution.

"Zombies" in the list of running Linux processes

Often in zombie processes can be seen in the list of running Linux processes(the status column for such processes contains the letter Z). Such processes are formed if a command was called to terminate a process whose parent is not yet running and which may need to access this process. The Z process does not use any resources.

You can view the parents of zombie processes with the command

Ps-lax
To remove "zombies" from the list of running Linux processes must be terminated parent process.

A process is an abstraction used to describe a running program. A process is a system object through which you can control a program's access to memory, CPU, and I/O resources. In Linux and Unix operating systems, system and user processes are subject to the same rules, so control is carried out using a single set of commands.

A process consists of an address space and a set of data structures contained within the kernel. The address space is the collection of memory pages that have been allocated by the kernel for the execution of a process. It loads the code and the function libraries it uses, as well as variables, the contents of stacks, and various supporting information that the kernel needs to run the process. Since UNIX and Linux systems support the concept of virtual memory, the pages of a process's address space at a particular time can be located either in physical memory or in the swap partition, i.e. on disk.

The kernel data structure stores all sorts of information about each process. The most important include:

  • Memory allocation table
  • Current status (inactive, suspended, running, etc.)
  • A priority
  • Information about the resources used
  • Information about files and network ports opened by the process
  • Signal mask (a record of which signals are blocked)
  • Process owner name

A thread of execution, commonly referred to simply as a thread, represents the result of a branch in the execution of a process. A thread inherits many of the attributes of its process, and within one process several threads can execute simultaneously (in parallel) - this execution model is called multithreading. In older single-processor systems, parallel execution is modeled by the kernel, but in multi-core and multiprocessor architectures, threads can execute simultaneously on different cores. Multi-threaded applications such as BIND and Apache benefit most from multi-core systems because these applications can process multiple requests simultaneously.

Process Attributes

The kernel assigns each process a unique ID PID. PID – Process ID. Most commands and system calls that operate on processes require a specific identifier to be specified so that the context of the operation is clear. IDs are assigned in order as processes are created.

Neither UNIX nor Linux has a system call that initiates a new process to execute a specific program. In order to spawn a new process, an existing process must clone itself. A clone can replace a running program with another.

In a cloning operation, the original process is called the parent process and its clone is called the child process. In addition to its own identifier, each child process has a PPID (Parent Process ID) attribute, which matches the identifier of the child process that spawned it. It is worth noting that PPID is very useful information if you have to deal with unknown processes. Tracing the origins of a process can make it easier to understand its purpose and significance.

When the system boots, the kernel itself starts several processes. The most important of them is the demon init, whose id is always 1. Daemon init Responsible for executing system startup scripts. All processes except those created by the kernel are descendants of the init daemon.

UID (User ID) is the identifier of the user who created this process. Only its creator (owner) and superuser can change the attributes of a process. EUID (Effective User ID) is the current user identifier of a process, designed to determine which resources and files a process currently has access to. Most programs have the same UID and EUID values. The exception is for programs that have the change user identifier (setuid) bit set.

GID (Group ID) is the group identifier to which the process owner belongs. The current group ID (EGID) is associated with the GID attribute in the same way that an EUID value is associated with a UID.

Process priority determines how much CPU time a program receives. The kernel uses a dynamic priority calculation algorithm that takes into account how much CPU time a process has already used and how much time it has been waiting in its queue.

Process life cycle

Process creation is the transition of a process from the “New” state to the “Ready” state. When a process is created, the operating system prepares a data structure for it. The new process is assigned its own PID, and resource accounting is maintained independently of the ancestor. The fact that a process exists does not give it the right to use CPU resources.

The ready process has received all the necessary resources and is waiting for the system scheduler to grant it access to the central processor. When access is granted, the process starts and enters the active state (running).

There are two ways from the “Started” state:

  1. Timeout – the process has worked and freed up processor resources (went to the queue)
  2. Waiting – the process is put into standby mode, where it waits for a certain signal

If a process makes a system call that cannot be completed immediately, the kernel puts it into sleep mode. A waiting process waits for a specific event to occur, be it data from a terminal or from a network connection. Many system daemons spend most of their time in this state. It is important to note that in this case the process will continue to be stored in RAM.

Some operations place the process in a continuous waiting (suspended) state. In this state, the process waits for a specific signal from the hardware and does not respond to other signals. In this case, the process is unloaded from RAM onto the hard drive (swap partition). In order to get rid of such a process, you need to eliminate the problem that gave rise to them or reboot the system.

After the process has completed, it is destroyed.

A zombie is a process that has finished executing, but information about it has not yet reached the parent process. When a process terminates, it releases all its resources (except for the PID) and becomes a “zombie” - an empty entry in the process table that stores the termination code for the parent process.

All processes are queued to execute commands. In this case, there are several queues depending on the status of the process: a ready queue and a blocked queue. After the work is completed, the process moves to the beginning of the queue and again waits for its moment to access the resources of the central processor.

Working with Processes in Linux

You can view a list of all processes running at the current time using the command ps. Using the command ps you can get information about the identifiers, priority and control terminal of a particular process. It also allows you to find out how much RAM a process is using, how much CPU time it took to execute, and the state of the process (running, stopped, idle, etc.). You can get a list of all processes using the following command:

user@ubuntu$ ps aux

Key a used to display all processes, key x– displays processes detached from the terminal, key u– provides filtering by the name or ID of the user who launched the program.

The meaning of the columns in the command output ps aux:

  1. USER – process owner name
  2. PID – process identifier
  3. %CPU – the percentage of CPU time that is spent on this process (in percent)
  4. %MEM – part of real memory that is spent on this process (in percent)
  5. VSZ – virtual process size
  6. RSS – number of memory pages
  7. TTY – control terminal identifier
  8. STAT – current process status (R-running, D-waiting for disk writes, S-inactive, T-suspended, Z-zombie)
  9. TIME – the amount of CPU time spent executing this process
  10. COMMAND – command name and arguments

The results of the ps lax command are shown below in abbreviated form. Pay attention to the additional fields PPID (parent process identifier), NI (compliance factor), WCHAN (resource that the process is waiting on).

NI essentially displays the priority of a process. The lower the value, the more priority it will be executed by the processor. The values ​​vary from -20 to 20.

It is very convenient to search for the process ID using a bunch of commands ps And grep. PS displays a list of processes and then passes control to the grep command, which in turn selects the required process from the list. Example: let's find the PID for the cron process.

As you can see, the PID for the cron process is 879.

The ps command allows you to take only a one-time “snapshot” of the system. To dynamically track processes use the command top.

The most active processes are at the top. The top command also displays statistics on process statuses, the amount of CPU and RAM resources used.

Signals are interrupt requests implemented at the process level.

When a signal arrives, one of two events is possible. If a process has assigned a processing routine to a signal, then when called, it is provided with information about the context in which the signal was generated. Otherwise, the kernel performs the default actions on behalf of the process. These actions depend on the signal, and in some cases a memory dump is also created.

A memory dump is a file containing an image of a process's memory

The procedure for calling a handler is called signal interception. When the handler completes execution, the process resumes from the point where the signal was received.

To prevent some signals from entering the program, you can set them to be ignored and blocked. The ignored signal is simply passed through and does not affect the operation of the processor. The blocked signal is queued for processing, but the kernel does not require any action from the process until the signal is explicitly unblocked.

Over thirty different signals have been defined, and they have a wide variety of applications. The most common of them:

  1. KILL – unconditional termination of a process at the kernel level
  2. STOP – pauses the process execution
  3. CONT – resumes the process execution
  4. TSTP – generated by pressing CTRL + Z, pauses the process by the user
  5. TERM – request to terminate the program (the process cleans up and exits normally)
  6. QUIT is the same as TERM + a memory dump is created
  7. HUP – reset command
  8. BUS – bus error (indicates incorrect memory access)
  9. SEGV – segmentation error (indicates incorrect memory access)

KILL and STOP signals cannot be intercepted, blocked, or ignored.

Team kill used to send signals to a process. Kill has the following syntax:

user@ubuntu$ kill [-signal] PID

For example, let's kill the cron process. We previously found out that its PID = 879.

user@ubuntu$ kill -KILL 879

As you can see, the cron process has been removed. Kill signals must be sent with superuser rights. Also, before killing cron, I removed the respawn line in the cron.conf configuration file, which is located in the /etc/init/cron.conf folder.

Finally, I’ll tell you about one more interesting thing. Upstart is an OS initialization system that controls the launch of daemons during system boot. Upstart configuration files are stored in the /etc/init folder. There are several commands for working with Upstart.

user@ubuntu$ status [process name] – process status

user@ubuntu$ start [process name] – start the process

user@ubuntu$ stop [process name] – stop the process

user@ubuntu$ restart [process name] – process restart

Support the project

Friends, the Netcloud website is developing every day thanks to your support. We plan to launch new article sections, as well as some useful services.

You have the opportunity to support the project and contribute any amount you consider necessary.

To effectively manage Linux OS processes and services, you need to have a good understanding of what a process is from the OS point of view, and how the interaction between different types of processes occurs in the OS.

A process is a Linux OS object that consists of a memory address space and a set of data structures. Essentially, a process is a running program or service.

Each running process in Linux can spawn additional processes. The process that started the new process is called the parent process. The new process in relation to the process that created it is called a child.

Processes are not the same as tasks: processes are part of the operating system, whereas tasks are known only to the command processor in which they run. A running program contains one or more processes; a task consists of one or more programs executed as shell commands.

Each process in the Linux OS is characterized by a set of attributes that distinguishes this process from all other processes. These attributes include:

* Process ID (PID). Each process in the system has a unique identifier. Each new launched process receives a number one greater than the previous one.

* Parent Process ID (PPID). The process receives this attribute during its startup and is used to obtain the status of the parent process.

* Real and effective user identifiers (UID, EUID) and group identifiers (GID, EGID). These process attributes indicate that it belongs to a specific user and group. The real IDs are the same as the IDs of the user who started the process and the group to which it belongs. Effective - on whose behalf the process was launched. Process access rights to Linux OS resources using effective identifiers. If the special SGID or SUID bit is set on the executable file of a program, then the process of this program will have the access rights of the owner of the executable file.
Real identifiers are used to control the process (for example, kill). All identifiers are passed from the parent process to the child process.
To view these attributes, you can use the command by specifying the desired column display format.

* Priority or dynamic priority (priority) and relative or static (nice) process priority.
Static priority or nice priority ranges from -20 to 19, with a default value of 0. A value of –20 is the highest priority, nice priority is not changed by the scheduler, it is inherited from the parent or specified by the user. Dynamic priority is used by the scheduler to schedule the execution of processes. This priority is stored in the prio field of the process's task_struct structure. Dynamic priority is calculated based on the value of the pice parameter for a given task by calculating a premium or penalty, depending on the interactivity of the task. The user can only change the static priority of a process. In this case, only root can increase the priority. There are two process priority control commands in Linux: nice and renice.

* Process state. In Linux OS, each process is necessarily in one of the states listed below and can be transferred from one state to another by the system or user commands. The following process states are distinguished:

TASK_RUNNING- the process is ready for execution or is running (runnable). Denoted by the symbol R.

TASK_INTERRUPTIBLE- waiting process (sleeping). This state means that the process has initiated execution
any system operation and waits for its completion. Such operations include input/output, termination of a child process
etc. Processes with this state are denoted by the symbol S.

TASK_STOPPED- process execution is stopped (stopping). Any process can be stopped. This can be done as a system,
so does the user. The state of such a process is indicated by the symbol T.

TASK_ZOMBIE- completed process (zombie). Processes in this state occur when the parent process
without waiting for the completion of the child process, it continues to work in parallel. Processes with this state are indicated by the symbol Z.
Processes that terminated are no longer running on the system, but still continue to consume non-computing resources.

TASK_UNINTERRUPTIBLE-uninterruptible process. Processes in this state are waiting for the operation to complete
I/O with direct memory access. Such a process cannot be terminated until the I/O operation completes.
Processes with this state are indicated by the symbol D. The state is similar to TASK_INTERRUPTIBLE, except that the process
does not resume execution when a signal is received. Used when a process must wait continuously or
when it is expected that some event may occur quite often. Since the task in this state does not respond
on signals, TASK_UNINTERRUPTIBLE is used less frequently than TASK_INTERRUPTIBLE.

Process types In Linux, processes are divided into three types:

  • System processes - are part of the kernel and are always located in RAM. System processes do not have corresponding programs in the form of executable files and are launched when the system kernel is initialized. The executing instructions and data of these processes reside in the kernel of the system, so they can call functions and access data that other processes cannot access. System processes, for example, are: shed (swap manager), vhand (page replacement manager), kmadaemon (kernel memory manager).
  • Demons - these are non-interactive processes that are launched in the usual way - by loading their corresponding programs (executable files) into memory, and are executed in the background. Typically, daemons are launched during system initialization (but after the kernel is initialized) and ensure the operation of various subsystems: terminal access systems, printing systems, network access and network services systems, mail server, dhcp server, etc. Daemons are not associated with any user session and cannot be directly controlled by the user. Most of the time, daemons wait for a process to request a certain service, such as accessing a file archive or printing a document.
  • Application (user) processes . Application processes include all other processes running on the system. Typically, these are processes spawned within a user session. For example, the ls command will spawn the corresponding process of that type. The most important application process is the command interpreter (shell), which enables you to work in LINUX. It starts immediately after registration in the system. Linux application processes can run either interactively or in the background, but in either case their lifetime (and execution) is limited to the user's session. When you log out, all application processes will be destroyed.

Process hierarchy

Linux implements a clear hierarchy of processes in the system. Each process in the system has only one parent and can have one or more child processes.

Rice. 3.1 – Fragment of the process hierarchy

During the final boot phase, the kernel mounts the root filesystem and configures the null process's runtime by creating process space, initializing the null entry point in the process table, and making the root directory current for the process. When the process execution environment is completed, the system is executed as a null process. The null process "forks" by running a fork directly from the kernel, since the process itself is running in kernel mode. The code executed by child process 1 includes a call to the exec system function, which launches the program from the file "/etc/init" for execution. Unlike process zero, which is a system-level process running in kernel mode, process 1 is a user-level process. Typically process 1 is called the init process because it is responsible for initializing new processes. In fact, you can put any program in /sbin/init and the kernel will run it as soon as it finishes loading. init's job is to start everything else as needed.

Init reads the /etc/inittab file, which contains instructions for further operation. The first instruction is usually to run the init script. On Debian based systems the init script will be /etc/init.d/rcS, on Red Hat it will be /etc/rc.d/rc.sysinit. This is where file systems are checked and mounted (/etc/fstab), system time clock is set, swap partition is enabled, hostname is assigned, etc. Next, the following script will be called, which will take us to the default “run level”. This simply means some set of daemons that need to be running.

Syslogd (/etc/init.d/syslogd) – a script responsible for starting and stopping the system logger (the SYSLOG event logging system allows you to record system messages in the /var/log log files).

Xined – Internet services daemon, manages services for the Internet. The daemon listens to sockets and if there is a message in any of them, it determines which service this socket belongs to and calls the appropriate program to process the request.

crond – The cron daemon is responsible for viewing crontab files and executing commands entered into it at a specified time for a specified user. The crontab(1) program links to crond through the cron.update file, which is located in the crontab directory, typically /var/spool/cron/crontabs.

The last important action of init is to run some getty. Mingetty are virtual terminals whose purpose is to monitor user consoles.

getty launches the login program - the start of the user's session in the system. The task of login is to register the user in the system. And after successful registration, the user’s command interpreter (shell), for example, bash, is most often loaded, or rather, after registering the user, the program specified for this user in the /etc/passwd file is loaded (in most cases this is bash).

2. Launching processes

There are two ways to run processes depending on the type of process.

For user processes, launch is carried out interactively by entering an arbitrary command or running an arbitrary script. For system processes and daemons, initialization scripts (init scripts) are used. These scripts are used by the init process to launch other processes when the OS boots. Initialization scripts are stored in the /etc directory. Within this directory there are subdirectories called rcO.d - rc6.d, each of which is associated with a specific runlevel. Each of these directories contains symbolic links to init scripts located directly in the /etc/rc.d/init.d directory.

It should be noted that the /etc/init.d directory contains hard links to scripts in the /etc/rc.d/init.d directory, so when you change scripts in these directories, the changed data is displayed the same regardless of the path to the script file.

Viewing init scripts

Bee init scripts can be restarted or stopped, thereby controlling the status of the service to which they belong. These scripts are launched from the command line and have the following syntax:

/etc/init.d/script-name start|stoplrestart|condrestart|status|reload

Here, the specific name of the init script is used as the script-name, and the following values ​​can be used as arguments:

* start (Start the service); * stop (Stop the service); * restart (Stopping and then starting the service); * condrestart (Conditional stop and subsequent start of the service); * status (Getting the service status status); * reload (Re-reading the service configuration file). For example, to conditionally restart the sshd service, use the following command: # /etc/init.d/sshd condrestart Stopping sshd: [ ok ] Starting sshd: [ ok ] Conditionally restart the sshd service.

If the condrestart argument is used, the service will only be restarted if the service is already running on the system.

In Linux OS, to manage services, in addition to directly accessing the init script file, there is a special service command (second method), as an argument of which you must specify arguments similar to those used when directly launching daemons through init scripts:

# service sshd reload Reloading sshd: [ ok ] Using the service command.

This example reads the sshd service configuration file again.

However, in most cases only root can control daemons.

Process launch commands

To terminate a process, you need to send a signal to it using the kill command. To do this, you need to find out the Pid of the process using the ps command (for example, the Pid of the process is 11839) and send the process a signal to terminate, for example the SIGKILL signal:

or kill –SIGKILL 11839

or kill –KILL 11839

What are signals?

Signals are software interrupts. Signals in the Linux OS are used as a means of synchronization and interaction between processes and threads. A signal is a message that the system sends to a process or one process sends to another. From the user's point of view, when a process receives a signal, it looks like an interrupt occurs. The process stops executing and control is transferred to the signal processing mechanism (handler). After processing the signal, the process can resume its execution from the point at which it was interrupted.

First of all, each signal has its own name and number. All signal names begin with the sequence SIG. For example, SIGALRM is generated when the timer set by the alarm() function measures the specified period of time. Linux supports 31 signals (numbers 1 to 31).

Signals can be generated by various conditions:

1. Generated by the terminal, when a certain key combination is pressed, for example, pressing Ctrl+C generates a SIGINT signal, thus you can interrupt the execution of a program that has gotten out of control;

2. Hardware errors - division by 0, memory access error and others - also lead to the generation of signals. These errors are usually detected by the hardware, which notifies the kernel of their occurrence. The kernel then generates the appropriate signal and passes it on to the process that was running when the error occurred. For example, the SIGSEGV signal is sent to a process when it attempts to access an invalid memory address.

3. Another process (including both the kernel and the system process) that made the system call to send the kill() signal;

4. When executing the kill command.

The transmission of signals to a process in cases where it is generated by some other process can be considered as the implementation of signaling communication means.

When a signal is received, a process can request the kernel to perform one of three responses to the signal:

1. Forcefully ignore the signal (almost any signal can be ignored, except SIGKILL and SIGSTOP).

2. Process the signal by default: ignore it, stop the process, put it in a waiting state until another special signal is received, or shut down.

3. Intercept the signal (perform user-specified signal processing).

The types of signals and methods of their occurrence in the system are strictly regulated. Signal types are usually specified by numeric numbers, ranging from 1 to 31 inclusive, but when programming, symbolic signal names defined in system include files are often used.

A job is simply a unit of work on the command processor.

When you run a command, your current command processor identifies it as a task and monitors it. When a command is completed, the corresponding task disappears. Tasks are at a higher level than Linux processes; the Linux operating system knows nothing about them. They are just elements of the command processor. Here are some important terms from the task lexicon.

  • foreground job - Running on a shell, occupying a shell session so that you cannot execute another command.
  • background job - Running on a shell, but not occupying a shell session so that you can run another command on the same shell.
  • suspend (suspend) - Temporarily suspend an interactive process.
  • resume - Return to execution of a suspended task.

It is convenient to send tasks to the background that do not require user intervention. Examples of such tasks include software compilation and complex computing programs. For these applications, it is important to minimize the total execution time on a system loaded with other processes spawned, in particular, by interactive tasks.

If you run a command interactively from the shell and want stop executing the command immediately, enter Ctrl-C. The command processor will interpret Ctrl-C as "stop the current task immediately." So if you are outputting a very long file (say with the cat command) and want to stop the output, press Ctrl-C. In fact, pressing Ctrl-C will send a SIGINT signal to the current task.

To stop a program running in the background, you can make it interactive using the fg command and then press Ctrl-C, or use the kill command.

Linux also has process management commands, such as kill, pkill, pgrep, and killall. Below are some examples of their use:

$ pgrep -u tecmint top $ kill 2308 $ pgrep -u tecmint top $ pgrep -u tecmint glances $ pkill glances $ pgrep -u tecmint glances

If you would like to learn more about using these commands, the information is in the links below.

Please note that with their help you can terminate frozen applications that are slowing down your system.

Sending signals to a process

The fundamental way to control processes in Linux is to send them signals, of which there are quite a lot. You can view a list of all signals using the command:

$ kill -l

To send signals to a process, use the kill, pkill, or pgrep commands described above. However, a program will only respond to a signal if it is programmed to recognize such a signal.

Most signals are intended to be used by the system or programmers when writing code. The following signals may be useful to the user:

SIGHUP 1 – sent to a process when its controlling terminal is closed.
SIGINT 2 – sent to a process by its controlling terminal if the user interrupts the process with the keys.
SIGQUIT 3 – Sent to a process if the user sends a program exit signal.
SIGKILL 9 - this signal immediately terminates (kills) the process without performing any operations to clear files, logs, etc.
SIGTERM 15 is the program termination signal (it is sent by the kill command by default).
SIGTSTP 20 – sent to a process by its controlling terminal with a request to stop (terminal stop); is initiated when pressing .

The following are examples of using kill commands to kill Firefox when it hangs using a PID:

$pidof firefox $kill 9 2687 OR $kill -KILL 2687 OR $kill -SIGKILL 2687

To terminate a program using its name, use the pkill or killall commands:

$pkill firefox $killall firefox

Changing the priority of a process

In Linux, all active processes have a certain priority value (nice). Higher priority processes typically receive more CPU time than lower priority processes.

However, a user with root privileges can change the priority using the nice and renice commands.
In the top command output, the NI column displays nice values ​​for processes.

You can use the nice command to set the nice value of a process. Remember that a normal user can only assign a nice value from 0 to 20 to a process if they own the process.
Negative nice values ​​can only be used by the root user.

To lower the priority of a process, use the renice command:

$ renice +8 2687 $ renice +8 2103

In today's post I will talk about how processes work in Linux OS, and how to manage these same processes, about running processes in the background, about increasing/lowering the priority of processes.

In general terms, process is a program that runs in the computer's RAM. In reality, everything is much more complicated.

A multitasking system can run many programs. Each program can run many processes (read: subroutines). At the same time, at a single moment on the machine, only 1 process is running. That is, at a single moment in time, iron resources ( CPU time, memory, I/O port) can only be used by a single process. The queue in which a process is allocated a specific hardware resource is managed by the scheduler. At the same time, during the interruption of one process and the start (resumption) of another process, the state of the process (actions performed, at what stage the process is suspended) is remembered and written to the memory area. Scheduler in Linux - this is the part of the kernel responsible for the specified functionality. IN scheduler tasks It also includes tracking and assigning a certain priority to running processes so that the processes do not “interfere” with each other’s work, as well as the distribution of memory space so that the memory space of one process does not overlap with the space of another.

All new processes in Linux are generated by cloning an existing process by calling system functions clone(2) And fork(2)(from forking- generation). The new (spawned or child) process has the same environment as its parent, only the process ID number (so-called PID) differs. Life of a typical process in Linux can be represented by the following diagram:

In which the following steps can be described step by step:

  • /bin/bash process clones itself with fork() system call
  • this creates a clone of /bin/bash with a new PID (process identifier) ​​and PPID - equal to the PID of the parent
  • The clone executes the exec system call pointing to the executable file and replaces its code with the code of the executable file (the parent process waits for the child to complete - wait)
    • Moreover, if for some reason the child has completed its work, and the parent process was unable to receive a signal about this, then this process (child) does not release the occupied kernel structures and the process state becomes zombie. About the process states below...

Wikipedia provided a very clear diagram:

From the above, a logical question may follow: if a new process is always a copy of an existing one, then How is the very first process taken in the system?

The first process in the system is started when the kernel is initialized. This process is called init and has PID=1. This is the parent of all processes in the system.

What states can a process be in in Linux?

Each running process at any time is in one of the following states (also called process status):

  • Active (R=Running)– the process is in the execution queue, that is, it is either running at the moment or is waiting for the next CPU time slice to be allocated to it.
  • “Sleeping” (S=Sleeping)– the process is in an interruptible wait state, that is, it is waiting for some event, signal, or release of the required resource.
  • Is in a state uninterruptible wait (D=Direct)– the process waits for a specific (“direct”) signal from the hardware and does not respond to other signals;
  • Suspended (T)– the process is in trace mode (this state usually occurs when debugging programs).
  • "Zombie" (Z=Zombie) is a process whose execution has completed, but the kernel structures associated with it are not freed for some reason. One of the reasons for their appearance in the system may be the following situation. Typically, the parent process releases kernel structures associated with a process after receiving a termination signal from the child. But there are times when the parent process terminates before the child process. Processes that do not have a parent are called " orphans". "Orphans" automatically are adopted process init, which receives signals about their completion. If the parent process or init for some reason cannot receive a signal to terminate the child process, then the child process turns into a “zombie” and receives status Z. Zombie processes do not take up CPU time (that is, their execution stops) , but the corresponding kernel structures are not freed. In a sense, these are “dead” processes. Killing such processes is one of the responsibilities of a system administrator. I would like to note that the appearance of these processes indicates that something is wrong in the system, and most likely there is something wrong with the hardware, so we take memtest and MHDD and test-test. The possibility of crooked program code cannot be ruled out.

Also, speaking about processes in Linux, we can distinguish a special type of process - demons. This type of process runs in the background (like services in Windows), without a terminal, and performs tasks for other processes. This type of process on server systems is the main one.

Because In most cases, daemons in Linux are idle and wait for any data to arrive; therefore, they are needed relatively rarely, so keeping them constantly loaded in memory and wasting system resources on this is irrational. A demon was invented to organize the work of demons inetd or its more secure modification xinetd(e X tended I nter NET Daemon or extended Internet daemon). In the inetd (Xinetd) function we can distinguish:

  • set a limit on the number of servers to be launched (services, daemons)
  • monitoring connections on specific ports and processing incoming requests
  • restricting access to services based on ACLs (access control lists)

All processes in the system, no matter whether it is Linux or another OS, exchange some information with each other. From here you can ask the question: How does inter-PROCESS exchange occur?

In LINUX OS there are several types of interprocess exchange, or rather Interprocess Communication (IPC) tools, which can be divided into several levels:

local (tied to the processor and only possible within the computer);

-- channels

  1. pipe(they are also pipelines, also unnamed channels), I talked a lot about them in the last post, an example can be given: team1 | team2. Basically, pipe uses stdin, stdout and stderr.
  2. Named pipes (FIFO: First In First Out). This type of channel is created using mknod or mkfifo, and two different processes can refer to it by name. Example of working with fifo:

in the first terminal (we create a named pipe in the form of a pipe file and send data from the channel using a pipeline to the archiver):

# mkfifo pipe # ls -l total 0 prw-r--r-- 1 root root 0 Nov 9 19:41 pipe # gzip -9 -c< pipe >out

in the second terminal (we send data to the named pipe):

# cat /path/to/file > pipe

as a result, this will lead to compression of the transmitted data with gzip

-- signals

  • from the terminal, by pressing special keys or combinations (for example, pressing Ctrl-C generates SIGINT, and Ctrl-Z SIGTSTP);
  • system core:
    • when hardware exceptions occur (invalid instructions, memory access violations, system failures, etc.);
    • erroneous system calls;
    • to report I/O events;
  • one process to another (or to itself), using the kill() system call, including:
    • from shell, utility /bin/kill.

signal is an asynchronous notification of a process about an event. When a signal is sent to a process, the operating system interrupts the process's execution. If a process has installed its own signal handler, the operating system runs that handler by passing it information about the signal. If the process has not installed a handler, the default handler is executed.
All signals begin with "SIG..." and have numeric correspondences defined in the signal.h header file. The numerical values ​​of the signals may vary from system to system, although most of them have the same values ​​in different systems. The kill utility allows you to specify a signal either as a number or as a symbol.
Signals can be sent in the following ways:

-- shared memory

Shared memory is used to increase the speed of data transfer between processes. In a normal situation, information exchange between processes passes through the kernel. The shared memory technique allows information to be exchanged not through the kernel, but using some part of the virtual address space where data is placed and read from.

Once a shared memory segment is created, any user process can attach it to its own virtual space and operate on it as if it were a regular memory segment.

-- message queues

In general terms, message exchange looks something like this: one process puts a message into a queue through some system calls, and any other process can read it from there, provided that both the message source process and the message destination process use the same key for gaining access to the queue.

remote;

-- Remote Procedure Calls (RPC)

RPC is a type of technology that allows computer programs to call functions or procedures in another address space (usually on remote computers). Typically, an RPC technology implementation includes two components: network protocol(usually TCP and UDP, less often HTTP) for exchange in client-server mode and a language for serializing objects (or structures, for non-object RPC).

-- Unix sockets

UNIX sockets There are 2 types: local And network. Using local socket, it is assigned UNIX address and a special file will simply be created ( socket file) along a given path through which any local processes can communicate by simply reading/writing from it. Sockets represent a virtual object that exists as long as at least one of the processes refers to it. Using network socket, an abstract object is created associated with the operating system listening port and network interface and assigned to it INET address, which has the address of the interface and listening port.

high level

  1. Typically - software packages that implement an intermediate layer between the system platform and the application. These packages are designed to migrate an application's already proven communication protocols to a newer architecture. An example is: DIPC, MPI, etc. (not familiar to me, to be honest)

So. Let's summarize:

  • Linux has processes
  • each process can launch subprocesses (threads),
  • the creation of a new process is created by cloning the original one,
  • The parent of all processes in the system is the init process, launched by the system kernel at boot.
  • processes interact with each other using process interaction:
    • channels
    • signals
    • sockets
    • shared memory
  • Each process has properties (read: has the following context):
    • PID - process identifier
    • PPID - identifier of the process that generated this
    • UID and GID - process rights identifiers (corresponds to the UID and GID of the user from whom the process is running)
    • process priority
    • process state (executing, sleeping, etc.)
    • the process also has a table of open (used) files

Process management

Getting information about a process

Before you can manage processes, you need to learn receive the necessary information about processes. On Linux there is pseudo procfs, which in most distributions is mounted in a common file system in the directory /proc . This file system has no physical location, no block device such as a hard disk. All information stored in this directory is located in random access memory computer, is controlled by the OS kernel and is not intended to store user files. I wrote about the structure of this directory in the article. This file system provides a lot of information to learn about processes and the system as a whole.

But using this directory is very inconvenient; to find out information about any process, you will have to look through a bunch of files and directories. To get rid of unnecessary labor, you can use existing ps utilities And top to view information about processes.

To get a list of all processes, just enter the command:

# ps aux

Let's comment on some interesting points. It can be noticed that some processes indicated in square brackets- these are processes that are directly part of the kernel and perform important system tasks, for example, such as managing the buffer cache and organizing swap. It’s better not to experiment with them - nothing good will come of it :). The rest of the processes are user processes.

What information can be obtained for each process (comments for some fields):

  • PID, PPID– identifier of the process and its parent.
  • %CPU– the proportion of processor time allocated to the process.
  • %MEM– percentage of RAM used.
  • VSZ– virtual size of the process.
  • TTY– control terminal.
  • STAT– process status:
    • R – running;
    • S – sleeping;
    • Z – zombie;
    • < – Повышенный приоритет;
    • + – Is in interactive mode.
  • START– start time.
  • TIME– execution time on the processor.

The ps command takes a snapshot of the processes currently running. In contrast, the top command dynamically displays the state of processes and their activity in real time.

Example output of the top command:

14:32:49 up 35 days, 6:01, 4 users, load average: 0.65, 0.51, 0.49 Tasks: 432 total, 1 running, 431 sleeping, 0 stopped, 0 zombie CPU0: 1.6%us, 3.6%sy, 0.0%ni, 85.3%id, 9.2%wa, 0.0%hi, 0.3%si, 0.0%st CPU1: 0.9%us, 1.9%sy, 0.0%ni, 96.9%id, 0.0%wa, 0.0%hi, 0.3 %si, 0.0%st Mem: 1033596K total, 1016644K used, 16952K free, 82928K buffers Swap: 2096376K total, 12632K used, 2083744K free, 478220K cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2788 root 15 - 5 0 0 0 S 2.0 0.0 404:43.97 md3_raid1 7961 root 20 0 5964 2528 1684 R 2.0 0.2 0:00.14 top 6629 root 20 0 8612 2884 2096 S 0.7 0.3 0:00.96 do vecot-auth 57 root 15 -5 0 0 0 S 0.3 0.0 4:36.10 kblockd/0 8703 ulogd 20 0 17700 4216 656 S 0.3 0.4 87:23.98 ulogd 11336 ldap 20 0 394M 15M 8292 S 0.3 1.5 5:29.28 slapd 257 57 ldap 20 0 394M 15M 8292 S 0.3 1.5 5:11.71 slapd 10991 root 20 0 2188 1004 588 S 0.3 0.1 4:23.33 dovecot 1 root 20 0 1712 516 464 S 0.0 0.0 0:46.17 init 2 root 15 -5 0 0 0 S 0.0 0.0 0:00.00 kthreadd 3 root RT -5 0 0 0 S 0.0 0.0 0:05.92 migration/0 ..... 2960 root 16 -4 1980 520 392 S 0.0 0.1 0:10.04 udevd 2993 dovecot 20 0 4412 1800 1476 S 0.0 0.2 0:00.00 pop3-login 2 994 dovecot 20 0 4412 1800 1476 S 0.0 0.2 0:00.02 pop3-login

The top of the output shows astronomical time, time elapsed since system startup, number of users in the system, number of running processes and number of processes in different states, data on CPU, memory and swap usage. And then there is a table characterizing individual processes. The number of rows displayed in this table is determined by the size of the window: the number of rows that fit, the number of rows that are displayed.

The contents of the window are updated every 5 seconds. List of processes can be sorted by CPU time used (default), by memory usage, by PID, by execution time. You can switch display modes using the following keyboard commands:

Using the command you can terminate some process (its PID will be requested), and using the command you can override the nice value for some process.

Useful information can also be obtained by the lsof program, which produces a list of all files currently used by processes, including directories occupied because some process uses them as the current or root directory; shared libraries loaded into memory; etc.

So now about process management.

Process Management in Linux

Each process is set at startup certain priority, which has a value from -20 to +20, where +20 is the most short. The priority of the new process is equal to the priority of the parent process. To change the priority of the program being launched, there is nice utility. An example of its use:

# nice [-adnice] command

Where adnice- value (from –20 to +19) added to the nice value of the parent process. Negative values ​​can only be set by the superuser. If the adnice option is not specified, the default nice value for the child process is 10 times the nice value of the parent process.

Renice Team serves to change the nice value for already running processes. The superuser can change the priority of any process on the system. Other users can change the priority value only for processes for which that user is the owner. In this case, an ordinary user can only reduce the priority value. Therefore, low priority processes cannot produce "high priority children".

As I already wrote, one of the process management tools is signals. Some signals can be generated using certain key combinations, but such combinations do not exist for all signals. But there is kill command, which allows you to send any signal to a given process (by specifying its PID):

# kill [-SIG] PID

Where S.I.G.- this is the signal number or signal name, and if the signal indication is omitted, then signal 15 is sent ( SIGTERM- software termination of the process). Signal 9 is often used ( KILL), with which the superuser can terminate any process. But this signal is very “rough,” so to speak, because it simply “kills” the process without giving it time to correctly save all processed data. Therefore, in most cases it is recommended to use signals TERM or QUIT, which complete the process more “softly”. If a process needs to respond to a signal in some special way, it can register handler, and if there is no handler, the system will react for it.

Two signals – 9 ( KILL) and 19 ( STOP) - Always processed by the system. The first one is needed to kill the process for sure(hence the name). STOP signal suspends process: in this state, the process is not removed from the process table, but is not executed until it receives signal 18 (CONT) - after which it continues to operate. In Linux, a STOP signal can be sent to an active process using the control character "^Z".

Regular users can only send signals to processes for which they are the owner. If in kill command use a process identifier (PID) equal to -1, then the signal specified in the command will be sent to all processes belonging to this user. The root superuser can send signals to any process. When the superuser sends a signal to ID -1, it is sent to all processes except system ones. If this signal is SIGKILL, then ordinary users will lose all open but not saved data files.

During normal startup, the process runs in the foreground. that is, the process "binds" to the terminal from which it is launched, accepting input from that terminal and producing output to it. But you can run the process in the background when it is not associated with the terminal, for which you add the & symbol at the end of the program launch command line.

There are two built-in commands that are used to bring processes to the foreground or return them to the background. fg command brings the process specified in the argument to the foreground, and bg team- puts the process into the background. With one bg command you can put several processes into the background at once, but you need to return them to the foreground one at a time. The arguments to the fg and bg commands can only be the numbers of jobs launched from the current shell instance. Possible task values ​​can be seen by running jobs team.

When a session ends, the shell sends a “hang up” signal to all processes it spawned, which can cause the processes it spawned to terminate, which is not always desirable. If you want to run a program in the background that should continue to run after you exit the shell, then you need to run it using the nohup utility:

# nohup team &

A process launched in this way will ignore signals sent to it (only signals SIGHUP And SIGQUIT). I also want to highlight pstree command, which shows the process tree. Very clear, by the way.