www.91084.com

GVKun编程网logo

Linux 入门到放弃之七《进程管理》(linux进程管理基础知识)

3

本文将分享Linux入门到放弃之七《进程管理》的详细内容,并且还将对linux进程管理基础知识进行详尽解释,此外,我们还将为大家带来关于boost:进程管理、CentOS中的网络管理+进程管理、Cen

本文将分享Linux 入门到放弃之七《进程管理》的详细内容,并且还将对linux进程管理基础知识进行详尽解释,此外,我们还将为大家带来关于boost:进程管理、CentOS中的网络管理+进程管理、CentOS基础:进程管理、Linux - 系统 - 进程管理的相关知识,希望对你有所帮助。

本文目录一览:

Linux 入门到放弃之七《进程管理》(linux进程管理基础知识)

Linux 入门到放弃之七《进程管理》(linux进程管理基础知识)

进程管理

1. 查看所有进程,并用全格式显示;

命令:ps -ef

2. 用 ps 命令查看系统当前的进程,并把系统当前的进程保存到文件 process 中;

命令:ps aux >> process

3. 用 top 查看系统状况,将更新显示二次的结果输出重定向到 /tmp/top.log 文件;

命令:top -n 2 >> /tmp/top.log

查看 top.log 文件

4. 用 ps 命令查看系统当前有没有 init 进程;

命令:ps aux | grep init

5. 查看 jerry 用户设置的计划任务;

命令:crontab -l -u jerry

如果没有 Jerry 用户,可以先添加 Jerry

6. 删除 Jerry 用户设置的计划任务;

命令:crontab -r -u jerry

7. 输入 cat "回车";

(1)按 ctrl + z 表示把该任务进程放到后台中 “暂停”

(2)输入 fg 表示把该任务放到前台运行;

(3)输入 ctrl + c 表示进程被终止;

8. 在根目录下查找名字以 ls 开头的所有文件,并把查询 结果保存到 tmp 文件中,此任务放在后台运行;

命令:find  /  -name  ls* > temp &

查看 temp 文件

9.jobs 命令查看后台执行的任务;

boost:进程管理

boost:进程管理

概述

Boost.Process提供了一个灵活的C++ 进程管理框架。它允许C++ developer可以像Java和.Net程序developer那样管理进程。它还提供了管理当前执行进程上下文、创建子进程、用C++ 流和异步I/O进行通信的能力。
该库以完全透明的方式将所有进程管理的抽象细节呈现给使用者,且该库是跨平台的。

特点

进程管理

Boost.Process的长期目标是提供一个抽象于操作系统之上的,可以管理任何运行的进程的框架。由于提供这样的API比较困难,所以现在只专注于管理。Boost.Process的最重要的特征就是启动一个外部应用、控制它们并与它们交互。传统上讲,对于C和C++ 来说,就比较困难了,因为它们要启动新进程、执行外部程序、建立匿名管道来交互、等待进程结束、检查进程退出码等。更糟糕的是不同操作系统,相关的进程模块和API是不同的。所以,Boost.Process的出现就提供了便利条件。

输入输出重定向

一般来说一个应用启动了子进程,它们可能会通过传输数据来交流。这种进程间通信是文件句柄层面的,通常涉及stdin、stdout、stderr。如果操作系统支持,那么就需要可重定向的流。不过这对C++ 来说是很容易的。

不同操作模式

支持同步、异步、分离

管道管理

这样就可以实现一个进程的输出可以作为另一个进程的输入。

库的设计图

最重要的类就是Context和Process。Context提供了进程运行的上下文。pistream和postream是为了交互。父进程还可以等待子进程退出,并检查进程退出码。如果有例如包含管道的shell命令要执行,那么pipeline_entry就应运而生了,它可以实现前一个子进程的输出是下一个子进程的输入。

使用步骤

1、创建上下文Context
2、创建子进程,获得子进程对象
3、如果有重定向,可以访问到stdin、stdout、stderr
4、进程结束,检查进程退出码

教程

一个最简单的例子

#include <boost/filesystem.hpp>
#include <boost/process.hpp>
#include <string>
#include <vector>
 
namespace  bp = ::boost::process;
 
bp::child start_child()
{
     std::string exec = "bjam" ;
     std::vector<std::string> args;
     args.push_back( "bjam" );
     args.push_back( "--version" );
 
     bp::context ctx;
     ctx.stdout_behavior = bp::capture_stream();
 
     return  bp::launch(exec, args, ctx);
}
 
int  main()
{
     bp::child c = start_child();
 
     bp::pistream &is = c.get_stdout();
     std::string line;
     while  (std::getline(is, line))
         std::cout << line << std::endl;
     bp::status s = c.wait();
 
     return  s.exited() ? s.exit_status() : EXIT_FAILURE;
}

下面再看一个异步的例子

#include <boost/filesystem.hpp>
#include <boost/asio.hpp>
#include <boost/process.hpp>
#include <boost/array.hpp>
#include <boost/bind.hpp>
#include <string>
#include <vector>
#include <iostream>
 
namespace  bp = ::boost::process;
namespace  ba = ::boost::asio;
 
ba::io_service io_service;
boost::array< char , 4096> buffer;
 
ba::posix::stream_descriptor in(io_service);
 
bp::child start_child()
{
     std::string exec = "bjam" ;
 
     std::vector<std::string> args;
     args.push_back( "bjam" );
     args.push_back( "--version" );
 
     bp::context ctx;
     ctx.stdout_behavior = bp::capture_stream();
     ctx.environment = bp::self::get_environment();
 
     return  bp::launch(exec, args, ctx);
}
 
void  end_read( const  boost:: system ::error_code &ec, std:: size_t  bytes_transferred);
 
void  begin_read()
{
     in.async_read_some(boost::asio::buffer(buffer),
         boost::bind(&end_read, ba::placeholders::error, ba::placeholders::bytes_transferred));
}
 
void  end_read( const  boost:: system ::error_code &ec, std:: size_t  bytes_transferred)
{
     if  (!ec)
     {
         std::cout << std::string(buffer.data(), bytes_transferred) << std::flush;
         begin_read();
     }
}
 
int  main()
{
     bp::child c = start_child();
 
     bp::pistream &is = c.get_stdout();
     in.assign(is.handle().release());
 
     begin_read();
     io_service.run();
 
     c.wait();
}

这个例子中用到了asio库,涉及到许多回调函数。关于异步(asio)暂时不做讲解,写这个例子是为了展示该库的异步功能。对异步感兴趣的同学可以看一下《Boost.Asio C++ Network Programming》

 

部分文件和类

stream_behaviour.hpp文件

对于流的描述,可分为六种类型

序号 流描述 含义
1 capture  父子进程之间通过无名管道相互接收数据 
2 close  启动时关闭 
3 inherit  父子进程共用一个,也即继承 
4 redirect_to_stdout  主要用在stderr时,重定向到stdout 
5 silence  输出重定向到/dev/null 
6 posix_redirect  将输出重定向到指定的文件描符,是对redirect_to_stdout的扩展 

以下是等价的
boost::process::child::get_stdin() <==> boost::process::posix_child::get_input(STDIN_FILENO)
boost::process::child::get_stdout() <==> boost::process::posix_child::get_output(STDOUT_FILENO)
boost::process::child::get_stderr() <==> boost::process::posix_child::get_output(STDERR_FILENO)

重定向的例子
#include <boost/process.hpp>
#include <boost/filesystem.hpp>
#include <string>
#include <vector>
#include <iostream>
#include <cstdlib>
#include <unistd.h>
 
namespace  bp = ::boost::process;
 
bp::posix_child start_child()
{
     std::string exec = bp::find_executable_in_path( "dbus-daemon" );
 
     std::vector<std::string> args;
     args.push_back( "dbus-daemon" );
     args.push_back( "--fork" );
     args.push_back( "--session" );
     args.push_back( "--print-address=3" );
     args.push_back( "--print-pid=4" );
 
     bp::posix_context ctx;
     ctx.output_behavior.insert(bp::behavior_map::value_type(STDOUT_FILENO, bp::inherit_stream()));
     ctx.output_behavior.insert(bp::behavior_map::value_type(STDERR_FILENO, bp::inherit_stream()));
     ctx.output_behavior.insert(bp::behavior_map::value_type(3, bp::capture_stream()));
     ctx.output_behavior.insert(bp::behavior_map::value_type(4, bp::capture_stream()));
 
     return  bp::posix_launch(exec, args, ctx);
}
 
int  main()
{
     try
     {
         bp::posix_child c = start_child();
 
         std::string address;
         pid_t pid;
         c.get_output(3) >> address;
         c.get_output(4) >> pid;
 
         bp::status s = c.wait();
         if  (s.exited())
         {
             if  (s.exit_status() == EXIT_SUCCESS)
             {
                 std::cout << "D-BUS daemon''s address is: "  << address << std::endl;
                 std::cout << "D-BUS daemon''s PID is: "  << pid << std::endl;
             }
             else
                 std::cout << "D-BUS daemon returned error condition: "  << s.exit_status() << std::endl;
         }
         else
             std::cout << "D-BUS daemon terminated abnormally"  << std::endl;
 
         return  s.exited() ? s.exit_status() : EXIT_FAILURE;
     }
     catch  (boost::filesystem::filesystem_error &ex)
     {
         std::cout << ex.what() << std::endl;
         return  EXIT_FAILURE;
     }
}
boost::process::context类
template  < class  Path>
class  basic_context : public  basic_work_directory_context<Path>, public  environment_context
{
public :
     /**
      * Child''s stdin behavior.
      */
     stream_behavior stdin_behavior;
 
     /**
      * Child''s stdout behavior.
      */
     stream_behavior stdout_behavior;
 
     /**
      * Child''s stderr behavior.
      */
     stream_behavior stderr_behavior;
};
 
typedef  basic_context<std::string> context;

而basic_work_directory_context是用来设置工作目录的;environment_context实质上是个包装了boost::process::environment的类,boost::process::environment是一个map<string, string>,用以保存环境变量。

boost::process::posix_context类
typedef  std::map< int , stream_behavior> behavior_map;
 
template  < class  Path>
class  posix_basic_context : public  basic_work_directory_context<Path>, public  environment_context
{
public :
     /**
      * Constructs a new POSIX-specific context.
      *
      * Constructs a new context. It is configured as follows:
      * * All communcation channels with the child process are closed.
      * * There are no channel mergings.
      * * The initial work directory of the child processes is set to the
      *   current working directory.
      * * The environment variables table is empty.
      * * The credentials are the same as those of the current process.
      */
     posix_basic_context()
         : uid(::getuid()),
         euid(::geteuid()),
         gid(::getgid()),
         egid(::getegid())
     {
     }
 
     /**
      * List of input streams that will be redirected.
      */
     behavior_map input_behavior;
 
     /**
      * List of output streams that will be redirected.
      */
     behavior_map output_behavior;
 
     /**
      * The user credentials.
      *
      * UID that specifies the user credentials to use to run the %child
      * process. Defaults to the current UID.
      */
     uid_t uid;
 
     /**
      * The effective user credentials.
      *
      * EUID that specifies the effective user credentials to use to run
      * the %child process. Defaults to the current EUID.
      */
     uid_t euid;
 
     /**
      * The group credentials.
      *
      * GID that specifies the group credentials to use to run the %child
      * process. Defaults to the current GID.
      */
     gid_t gid;
 
     /**
      * The effective group credentials.
      *
      * EGID that specifies the effective group credentials to use to run
      * the %child process. Defaults to the current EGID.
      */
     gid_t egid;
 
     /**
      * The chroot directory, if any.
      *
      * Specifies the directory in which the %child process is chrooted
      * before execution. Empty if this feature is not desired.
      */
     Path chroot;
};
 
/**
  * Default instantiation of posix_basic_context.
  */
typedef  posix_basic_context<std::string> posix_context;

函数boost::process::self::get_environment()可以得到当前进程的环境变量。
我们可以对环境变量进行修改,如
boost::process::environment_context env;
env.insert(boost::process::environment::valuetype(“A”, “a”));

进程结束码类信息
class  status
{
     friend  class  child;
 
public :
     /**
      * 进程是否正常退出
      */
     bool  exited() const ;
 
     /**
      * 进程返回值
      */
     int  exit_status() const ;
 
protected :
     status( int  flags);
 
     ...
};
 
class  posix_status : public  status
{
public :
     posix_status( const  status &s);
 
     /**
      * 进程是否因为信号终止
      */
     bool  signaled() const ;
 
     /**
      * 如果因为信号终止,那么是因为哪个信号终止的
      */
     int  term_signal() const ;
     /**
      * 是否core dump了
      */
     bool  dumped_core() const ;
 
     /**
      * 进程是否因为收到信号停止
      */
     bool  stopped() const ;
 
     /**
      * 如果进程因为收到信号停止,那么信号是哪个
      */
     int  stop_signal() const ;
}
进程类对象信息
class  process
{
public :
     typedef  pid_t id_type;
     process(id_type id);
 
     /**
      * Returns the process'' identifier.
      */
     id_type get_id() const ;
 
     /**
      * 强制终止一个进程,force为真则用SIGKILL杀死,否则用SIGTERM杀死
      */
     void  terminate( bool  force = false ) const  ;
private :
     ...
};
 
class  child : public  process
{
public :
     /**
      * 获得标准输出
      */
     postream &get_stdin() const ;
 
     /**
      * 获得标准输入
      */
     pistream &get_stdout() const ;
 
     /**
      * 获得标准错误输入
      */
     pistream &get_stderr() const ;
 
     /**
      * 阻塞等待进程退出,返回状态码对象
      */
     status wait();
 
     /**
      * 创建一个子进程对象
      */
     child(id_type id, detail::file_handle fhstdin, detail::file_handle fhstdout, detail::file_handle fhstderr, detail::file_handle fhprocess = detail::file_handle());
 
private :
     ...
};
 
class  posix_child : public  child
{
public :
     /**
      * 从指定描述符获得一个输出流
      */
     postream &get_input( int  desc) const ;
 
     /**
      * 从指定描述符获得一个输入流
      */
     pistream &get_output( int  desc) const ;
 
     /**
      *构造函数
      */
     posix_child(id_type id, detail::info_map &infoin, detail::info_map &infoout);
 
private :
     ...
};
children类

children类实际上std::vector<child>。children的启动方式是一个输出流被链接到下一个子进程的输入流上。

#include <boost/process.hpp>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <cstdlib>
 
namespace  bp = ::boost::process;
 
bp::children start_children()
{
     bp::context ctxin;
     ctxin.stdin_behavior = bp::capture_stream();
 
     bp::context ctxout;
     ctxout.stdout_behavior = bp::inherit_stream();
     ctxout.stderr_behavior = bp::redirect_stream_to_stdout();
 
     std::string exec1 = bp::find_executable_in_path( "cut" );
     std::vector<std::string> args1;
     args1.push_back( "cut" );
     args1.push_back( "-d " );
     args1.push_back( "-f2-5" );
 
     std::string exec2 = bp::find_executable_in_path( "sed" );
     std::vector<std::string> args2;
     args2.push_back( "sed" );
     args2.push_back( "s,^,line: >>>," );
 
     std::string exec3 = bp::find_executable_in_path( "sed" );
     std::vector<std::string> args3;
     args3.push_back( "sed" );
     args3.push_back( "s,$,<<<," );
 
     std::vector<bp::pipeline_entry> entries;
     entries.push_back(bp::pipeline_entry(exec1, args1, ctxin));
     entries.push_back(bp::pipeline_entry(exec2, args2, ctxout));
     entries.push_back(bp::pipeline_entry(exec3, args3, ctxout));
 
     return  bp::launch_pipeline(entries);
}
 
int  main( int  argc, char  *argv[])
{
     try
     {
         if  (argc < 2)
         {
             std::cerr << "Please specify a file name"  << std::endl;
             return  EXIT_FAILURE;
         }
 
         std::ifstream file(argv[1]);
         if  (!file)
         {
             std::cerr << "Cannot open file"  << std::endl;
             return  EXIT_FAILURE;
         }
 
         bp::children cs = start_children();
 
         bp::postream &os = cs.front().get_stdin();
         std::string line;
         while  (std::getline(file, line))
             os << line << std::endl;
         os.close();
 
         bp::status s = bp::wait_children(cs);
 
         return  s.exited() ? s.exit_status() : EXIT_FAILURE;
     }
     catch  (boost::filesystem::filesystem_error &ex)
     {
         std::cout << ex.what() << std::endl;
         return  EXIT_FAILURE;
     }
}

需要注意的是,wait_children出错时,返回第一个子进程的退出码,所有子进程都正常退出时,返回最后一个子进程的退出码。

 

master3中大量用到进程管理这个库。这个Boost.Process库可以在这里获得点这里。

 

CentOS中的网络管理+进程管理

CentOS中的网络管理+进程管理

nmcli命令:

command - line tool for controlling NetworkManager

格式:nmcli [OPTIONS] OBJECT { COMMAND | help }

OPTIONS: = {

-t [erse]

-p [retty]

-m [mode] tabular | multiline

-f [ields] <field1,field2,...> | all | common

-e [scape] yes | no

-v [ersion]

-h [elp]

}

OBJECT: connection | device

device - show and manage network interfaces

COMMAND := { status | show | connect | disconnect | delete | wifi | wimax }

status: 状态显示

connection - start,stop,and manage network connections

start: 启动

stop: 停止

manage: 管理

COMMAD := { show | up | down | add | edit | modify | delete | reload | load }

示例: nmcli general status 状态显示

modify: 改文件

reload: 重新加载

load: 加载

show: 显示所有网络连接的属性信息

up|down: 启动或禁用指定的网络连接

add: 添加新的网络连接

autoconnect yes|no: 是否自动启动此连接,在配置文件中添加ONBOOT=yes|no;

ifname IF_NAME: 指定要创建连接的目标网络接口设备名称;

con-name CON_NAME: 为指定的网络接口设备创建一个连接名称;

type TYPE: 指定网络设备的接口类型;

示例:

# nmcli connection add sutoconnect yes ifname eno67109432 con-name eno666 type ethernet

delete: 删除指定的网络连接

#nmcli connection delete CON_NAME

示例:

#nmcli connection delete eno666

reload: 不重启网络接口,但重新加载其配置文件中的配置信息;

modify:

modify [ id | uuid | path ] <ID> [+|-]<setting>.<property> <value>

<setting>:

802-3-ethernet.mtu

connection.autoconnect

ipv4.addresses

ipv4.dns

ipv4.gateway

ipv4.method

示例:

# nmcli connection modify "系统\ eno50332208" ipv4.addresses 1.2.3.4/8 ipv4.dns 202.202.222.222 ipv4.gateway 1.1.1.1

nmtui:

nmtui - Text User Interface for controlling NetworkManager

CentOS6:

system-config-network[-tui]

setup --> 网络配置

注意: 上述命令虽然可以使用简单的图形界面,但都是修改了配置文件,所以需要重启网络接口才能使配置生效;

网络组(Network Teaming)

网络组: 是将多个网络接口设备聚合在一起的方法,其目的是实现冗余容错以及提高可用性和吞吐量;

网络组与以往的Bonding技术相比,具有更好的性能以及更好的扩展性;

在CentOS7中,网络组是由内核中的一个内核驱动和一个名为teamd的守护进程来实现的;

网络组可以实现多个工作模式,被称为"运行器(runner)";

broadcast

roundrobin

activebackup

loadbalance

lacp(IEEE 802.3ad,Link Aggregation Control Protocol,链路聚合控制协议)

网络组连接的特点:

1.启动网络组接口并不会自动启动网络组中的其他port接口;

2.启动网络组终端port接口,也不会自动启动网路组接口;

3.禁用网络组接口,则会立即禁用网络组中的port接口;

4.对于没有port接口的网络接口而言,只能配置静态IP地址,不能设置从DHCP获取; 如果设置了,网络组接口就会一直等待port接口的加入;

创建网络组接口的方法:

nmcli connection add type team con-name TEAM_COM_NAME ifname IF_NAME config JSON

JSON是用来指定runner的方式,其格式:

'{"runner": {"name": "METHOD"}}'

示例:

# nmcli connectin add type team con-name class17 ifname class17config '{"runner": {"name": "loadbalance"}}'

# nmcli connection modify class17 ipv4.addresses 172.16.203.205/16

# nmcli connection modify class17 ipv4.method manual

创建port接口

nmcli connection add type team-slave [con-name CON_NAME] ifname IF_NAME master TEAM_NAME

注意: 如果不指定con-name,则默认的con-name为team-slave-IF_NAME

示例:

# nmcli connectin add type team-slave con-name eno67109432 ifname eno67109432 master class17

# nmcli connectin up class17

# nmcli connectin up eno67109432

# nmcli device disconnect eno67109432

创建网络组也可以直接改对应的连接的配置文件:

网络组接口:

DEVICE=class17

TEAM_CONfig="{\"runner\": {\"name\": \"activebackup\"}}"

DEVICETYPE=Team

BOOTPRORO=noe

NAME=class17

ONBOOT=yes

IPADDR=172.16.203.205

PREFIX=16

port接口:

NAME=team-slave-eno33554984

DEVICE=eno33554984

ONBOOT=yes

TEAM_MASTER=class17

DEVICETYPE=TeamPort

进程管理

在进程管理中,经常会需要进行保存现场和恢复现场

保存现场: 将数据和状态保存

恢复现场: 将数据和状态恢复

在linux中进程和线程基本无差别

在windows中划分明显,一个cpu只能执行一个进程;

写时复制: 即在数据发生改变时,对数据进行复制;

所谓进程: process,一个活动的程序实体的副本;

生命周期可能包含一个或多个执行流;

创建进程:

每个进程的组织结构是一致的;

内核在正常启动并且全面接管硬件资源之后,会创建一个Init的进程; 而这个名叫init的进程负责用户空间的进程管理;

CentOS5及以前: SysV Init,Classic Init

有缺陷: 在启动系统时,Init通过写脚本的方式来创建各个子进程; 利用shell来实现,因此其执行速度非常慢; 导致系统的启动速度和进程的创建速度都非常慢;

CentOS6: upstart,由Ubuntu研发的新型的Init进程; 可以并行的启动某些有关联的服务进程; 在创建进程的时候,可以多创建进程; 如果有多个cpu或这个多颗cpu核心的话,其进程的创建速度会有比较明显的变化; 第一个进程名称仍然是init;

CentOS7: Systemd(系统的守护神),参考了MAC OS的启动逻辑开发的一款新款的init程序; 其可以自身独立完成整个操作系统的启动工作; 也就是说,在开机并加载内核之后,只需要启动一个systemd进程就可以将其他各服务进程启动起来,从而引导整个系统启动;

除了init进程之外,其他的各个进程都是由其父进程创建的;

由fork()系统调用来实现的;

每个父进程通过fork()系统调用,复制自身的数据给子进程使用; 这种复制方式不是立即复制,而是写时复制(CoW);

终止进程:

任何父进程创建的子进程都必须由父进程亲自销毁;

任何的进程的父子关系都保存在task struct中;

进程优先级:

0-139个等级;

0保留没用

实则1-139

1-99: 实时优先级,数字越大优先级越高; 在系统启动时启动的进程;

100-139: 静态优先级,数字越小优先级越高;

在用户执行某些应用程序的时候启动的进程;

nice值:

-20~19: 默认的nice值0;

只有管理员才能使用负整数的nice值,以提升进程的优先级;

而普通用户只能使用正整数的nice值,以降低进程的优先级;

划分了140个进程队列;

Big O标准:

O(1),O(logN),O(N),O(N^2),O(2^N)

进程的类型:

按照进程的启动方式:

守护进程:

Daemon,通常是在系统引导的过程被启动的,与任何的终端无关; 也可以通过终端启动;

用户进程:

用户登录到系统之后,通过终端启动的进程;

按照进程的运行位置:

前台进程:

在进程启动之后,进程一直占用标准输出或者标准输入或者同时占用标准输出和标准输入;

后台进程:

在进程启动之后,进程不占用标准输出和标准输入;

按照进程对于资源消耗:

cpu-Bond: 非交互式的进程;

IO-Bond: 编辑器等各种交互式进程;

Linux系统上与进程有关的命令(查看命令和管理类命令):

pstree,ps,pidof,pgrep,pkill,top,htop,glances,dstat,pmap,vmstat,bg,fg,jobs,kill,killall,nohup,nice,renice,......

pstree:

pstree - display a tree of processes

ps

ps - report a snapshot of the current pocesses.

ps [options]

1. UNIX options,which may be grouped and must be preceded by a dash.

2. BSD options,which may be grouped and must not be used with a dash.

3. GNU long options,which are preceded by two dashes.

常用选项:

BSD风格的选项:

a: 显示所有与终端相关的进程;

x: 显示所有与终端无关的进程;

u: 显示发起进程的用户的账户名称;

常用的选项组合之一: aux

ps aux命令显示的结果中各字段的含义:

USER: 进程的所有者

PID: 进程标识符

%cpu: 进程占用的cpu处理时间的百分比;

%MEM: 进程占用的物理内存的百分比;

VSZ: 虚拟内存集(可交换内存集)

RSS: 常驻内存集

TTY: 进程与哪个终端相关; ? 表示与终端无关

STAT

R: running,正在运行的进程;

S: interuptible sleeping,可中断的睡眠状态;

D: uninteruptible sleeping,不可中断的睡眠状态; disk Block;

T: Trace/STOPPED,被跟踪/已停止; (通常是子进程在等待父进程将其杀死)

Z: Zombie,僵死态;

+: 前台进程

l: 包含多线程的进程

<: 高优先级进程

N: 低优先级进程

s: session leader,由子进程的父进程;

START: 进程开始执行的时候时间戳

TIME: 进程累计的cpu占用时间

COMMAND: 启动进程的命令行参数

UNIX风格的选项:

-e: 显示所有进程;

-f: 显示完整格式的进程信息

-F: 显示完整格式的进程信息,与-f几乎相同;

常用的选项组合之二: -ef

PPID: 父进程PID

C: 表示进程占用的cpu时间的百分比

常用的选项组合之二: -eF

SZ: 虚拟内存集

RSS: 常驻内存集

PSR: 表示此进程在哪个cpu核心上运行;

-H: 以层级结构显示进程的父子关系;

常用的选项组合之四: -eFH

o|-o field1,...: 以自定义字段的方式显示进程相关信息;

field: pid,ppid,ni,rtprio,psr,pcpu,stat,comm,user,tty,vsz,RSS,......

常用的选项组合之五: -eo | axo field1,...

pgrep,pkill:

pgrep,pkill - look up or signal processes based on name and other attributes

根据进程名称或其他属性查看进行或向进程发送信号;

pgrep [options] pattern

pkill [options] pattern

常用选项:

-u uuid: 显示进程的有效用户;

-U uid: 显示进程的真实用户;

-t TERM: 显示指定的终端相关的进程;

-l: 显示进程名称;

-a: 显示进程的完整的命令行参数;

pidof:

显示指定进程名称对应的进程ID;

top:

top - display Linux processes

top首部:

第一行: uptime信息:

当前系统时间

系统的运行时长

当前登录系统的用户总数

过去1分钟,5分钟,15分钟的在cpu上等待运行的进程队列的长度;

第二行:

系统中运行的进程总数;

正在运行的进程数;

处于睡眠状态的进程数

已停止的进程数

僵死态的进程数

第三行: cpu时间占用百分比

us: user space,用户空间的进程占用的cpu时间的百分比

sy: system,内核空间的内核进程占用的cpu时间的百分比

ni: nice,使用nice值调整了进程优先级之后额外多占用的cpu时间百分比;

id: idle,cpu空闲时间的百分比

wa: waiting,等待IO完成所消耗的cpu时间的百分比

hi: hardware interupting,处理硬件中断时间所消耗的cpu时间的百分比;

si: software interupting,处理软件中断时间所消耗的cpu时间的百分比;

st: stolen,被虚拟化程序等偷走的cpu时间的百分比

第四行: 以KB为单位显示物理内存空间的使用情况;

total: 物理内存空间的总大小

free: 空闲的物理内存空间大小

userd: 已经被使用的物理内存空间大小

buffer/cache: 缓冲区和缓冲区消耗的物理内存空间大小

auail mem: 真正可用的内存空间大小;

第五行: 以KB为单位显示swap空间的使用情况

交互式命令:

1: (数字) 显示或隐藏cpu核心信息

P: 根据cpu占用百分比进行排序

M: 根据物理内存占用百分比进行排序

T: 根据累计cpu占用时间进行排序

l: (字母)关闭或显示uptime信息

t: 关闭或显示第二,第三行信息

m: 关闭或显示第四,第五行信息

q: 退出top交互模式

s: 修改top的刷新时间间隔

k: 终止某个指定PID的进程的运行

常用的选项:

-d #: 指定top刷新的时间间隔,默认是3秒;

-b: 按批次显示进程信息

-n #: 通常与-b选项一起使用,表示显示多少批;

CentOS基础:进程管理

CentOS基础:进程管理

进程是操作系统上非常重要的概念,所有系统上面跑的数据都会以进程的类型存在。在 Linux 系统当中:触发任何一个事件时,系统都会将它定义成为一个进程,并且给予这个进程一个 ID,称为 PID,同时根据触发这个进程的用户,给予这个 PID 一组有效的权限设置。

进程是什么样的

程序运行起来后,我们看不到也摸不着。因此 Linux 为我们提供了一系列方便的命名来查看正在运行的进程。首先是 ps 命令,比如ps -l命令能查看当前 bash 下的相关进程全部信息。如下:

$ ps -l F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 0 S 1000 2552 2538 0 80 0 - 1945 wait pts/0 00:00:00 bash 0 S 1000 9352 2552 0 80 0 - 1926 wait pts/0 00:00:00 bash 0 R 1000 9478 9352 0 80 0 - 1598 - pts/0 00:00:00 ps

另外,我们还可以用pstree命令来显示整棵进程树。

CentOS基础:进程管理

可以看到这里 init 进程是所有进程的根节点,使用ps命令还能看到 init 的 PID 为 1 。当Linux启动的时候,init 是系统创建的第一个进程,这一进程会一直存在,直到我们关闭计算机。所有其他的进程都是由 init 进程衍生出来的。

父进程 & 子进程

上面提到所谓的“衍生出来的进程”正是 Linux 的父子进程的概念。当我们登录系统后,会取得一个 bash shell,然后我们利用这个 bash 提供的接口去执行另一个命令,例如bash或者ps等。那些另外执行的命令也会被触发成为 PID,那个后来执行的命令产生的 PID 就是“子进程”,而原本的 bash 环境下,就称为“父进程”了。

老进程成为新进程的父进程(parent process),而相应的,新进程就是老的进程的子进程(child process)。一个进程除了有一个PID之外,还会有一个PPID(parent PID)来存储的父进程 PID。如果我们循着 PPID 不断向上追溯的话,总会发现其源头是 init 进程。所以说,所有的进程也构成一个以 init 为根的树状结构。

我们使用ps -o命令来看一看现有的进程。

$ ps -o pid,ppid,comm PID PPID COMMAND 2552 2538 bash 9352 2552 bash 9625 9352 ps

我所做的操作是在原来的 bash shell 中执行了 bash 命令,然后又执行了 ps 命令。我们可以看到,第二个进程 bash 是第一个进程 bash 的子进程,而第三个进程ps是第二个进程的子进程。

fork & exec

当计算机开机的时候,内核(kernel)只建立了一个 init 进程。Linux kernel 并不提供直接建立新进程的系统调用。剩下的所有进程都是 init 进程通过 fork 机制建立的。新的进程要通过老的进程复制自身得到,这就是 fork。fork 是一个系统调用。进程存活于内存中。每个进程都在内存中分配有属于自己的一片空间 (内存空间,包含栈、堆、全局静态区、文本常量区、程序代码区)。当一个程序调用 fork 的时候,实际上就是将上面的内存空间,又复制出来一个,构成一个新的进程,并在内核中为该进程创建新的附加信息 (比如新的 PID,而 PPID 为原进程的 PID)。此后,两个进程分别地继续运行下去。新的进程和原有进程有相同的运行状态(相同的变量值,相同的指令…)。我们只能通过进程的附加信息来区分两者。
程序调用 exec 的时候,进程清空自身的内存空间,并根据新的程序文件重建程序代码、文本常量、全局静态、堆和栈(此时堆和栈大小都为 0),并开始运行。

工作管理

这个工作管理(job control)是用在 bash 环境下的,也就是说,当我们登录系统取得 bash shell 之后,在单一终端机下可以同时进行多个工作的行为管理。

假如我们只有一个终端,因此在可以出现提示符让你操作的环境就成为前台(foreground),至于其他工作就可以放在后台(background)去暂停或运行。

工作管理的意义在于将多个工作囊括在一个终端,并取其中的一个工作作为前台,来直接接收该终端的输入输出以及终端信号。 其他工作在后台运行。

  • 直接将命令丢到后台执行:&

    $ping localhost > log &

    此时终端显示:

    [1] 9800

    括号中的 1 表示工作号,而 9800 为 PID

  • 将目前的工作丢到后台中“暂停”:[ctrl]+z

    $vim ~/.bashrc

    在vim的普通模式下,按下[ctrl]+z的组合键

    [2]+ 已停止 vim ~/.bashrc

  • 查看目前的后台工作状态:jobs
    其各个参数的含义如下
    -l :同时列出PID的号码
    -r:仅列出正在后台run的工作
    -s:仅列出在后台stop的工作

    例如我们执行

    $ jobs -l [1]- 9800 运行中 ping localhost > log & [2]+ 9905 停止 vim ~/.bashrc

    能看到目前有多少个工作在后台中,并且能看到这些工作的 PID。紧跟在 job number 后面的+代表最近放到后台的工作,-代表最近最后第二个放到后台的工作,直接执行fg的话会先取+

  • 将后台工作拿到前台来处理:fg %jobnumber

    $cat > log & $fg %1

    当我们运行第一个命令后,由于工作在后台,我们无法对命令进行输入,直到我们将工作带入前台,才能向 cat 命令输入。在输入完成后,按下 CTRL+D 来通知 shell 输入结束。

  • 让工作在后台下的状态变成运行中:bg %jobnumber

  • 管理后台工作中的工作:kill
    信号可以通过 kill 传递给进程,信号值以下三个比较重要。
    -1 重新加载 (SIGHUP)
    -9 立刻删除 (SIGKILL)
    -15 正常终止(SIGTERM)

    可以使用

    $kill -SIGTERM 9800

    或者

    $kill -15 %1

    的方式来发送给工作。上面的两个命令,一个是发送给信号给 PID 9800 ,一个是发送信号值给工作号1,两者等价。

  • 监控进程的变化:top
    top 是一个很不错的程序查看工具,但不同于 ps 的静态结果输出,top 可以持续监测整个系统的进程工作状态,而且功能非常丰富,可以在 top 中输入?查看更多功能按键。常用的有P以cpu使用资源排序,M以物理内存使用排序。

    常用的参数有-d可以修改进程界面更新的秒数,-p可以指定某些个 PID 来进行查看监测。

参考资料

  • 鸟哥的Linux私房菜.基础学习篇

Linux - 系统 - 进程管理

Linux - 系统 - 进程管理

吴宏东 - 记于2018年06月19日 - 博客 https://segmentfault.com/u/wu...

Linux 进程管理

进程概述

父子进程

PID:进程的唯一标识号;
systemd:系统启动后第一个进程,PID=1;
login:systemd进程会创建login进程,所以,systemd是login的父进程,反之login是systemd的子进程;
shell:shell(默认是bash)是login进程创建的,其后用户的所有进程都由该进程派生创建;

进程标识

RUID:实际用户识别号;
RGID:实际组识别号;
EUID:有效用户识别号;
EGID:有效组识别号;
RUID和RGID的作用是识别正在运行此进程的用户和组;
如果程序没有设置SUID和SGID,那么EUID和EGID就是RUID和RGID,而RUID和RGID就是用户和组的UID和GID;

进程类型

交互进程:由shell启动的进程,可以前台或后台运行;
批处理进程:不与特定终端关联,加入后台的计划队列顺序处理;
守护进程:系统初始化后,需要运行于后台的进程;

查看进程

命令 ps -aux

[-a]:显示所有进程;
[-u]:显示用户名和启动时间等信息;
[-x]:显示没有控制终端的进程;
[-w]:显示完整命令行;

# 查找关于openshift的进程
ps -aux|grep openshift;
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.0  0.1 128020  6620 ?        Ss   10:33   0:02 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root          2  0.0  0.0      0     0 ?        S    10:33   0:00 [kthreadd]
root          3  0.0  0.0      0     0 ?        S    10:33   0:00 [ksoftirqd/0]
root          5  0.0  0.0      0     0 ?        S<   10:33   0:00 [kworker/0:0H]
root          6  0.0  0.0      0     0 ?        S    10:33   0:01 [kworker/u256:0]

USER:用户名;
PID:进程号;
%CPU:占用CPU时间与总时间的百分比;
%MEM:占用内存与系统内存总量的百分比;
VSZ:占用虚拟内存空间,单位KB;
RSS:占用内存空间,单位KB;
TTY:从哪个终端启动;
STAT:进程当前状态;
START:开始执行时间;
TIME:自启动以来占用CPU的总时间;
COMMAND:启动命令名;

状态:R 执行中;S 睡眠;T 追踪或停止;Z 僵尸进程;< 高优先级;N 低优先级;

命令 pgrep

通过模糊匹配模式,查找进程的ID

# 查找关于openshift的进程ID
pgrep openshift;

命令 pidof

通过模糊匹配模式,查找进程的ID

# 查找关于openshift的进程ID
pidof openshift;

杀死进程

命令 kill

# 杀死指定PID为10086的进程
kill 10086;
# 强制杀死进程
kill -9 10086;
# 杀死进程名为openshift的进程
kill openshift;
kill -9 $(pgrep openshift);

命令 killall

# 杀死进程名为openshift的所有进程
killall openshift;

命令 pkill

# 杀死进程名为openshift的所有进程
pkill openshift;

作业进程

cmd &:表示后台执行;
nohup cmd &:表示后台执行,并且用户注销后仍然运行着;
<Ctrl+D>:正常终止一个前台运行的进程;
<Ctrl+C>:强行终止一个前台运行的进程;
<Ctrl+Z>:挂起一个正在前台运行的进程;
<Ctrl+S>:挂起终端;
<Ctrl+Q>:解除挂起终端;

命令 [cmd] &

# 终端休眠100秒,调度到后台运行
sleep 100 &;

命令 nohup [cmd] &

# 终端休眠100秒,调度到后台运行,且用户注销后仍然运行着
nohup sleep 100 &;

命令 jobs

# 查看正在运行的作业
jobs;
# 显示进程PID
jobs -l;
[root@master ~]# jobs -l
[1]+  1810 完成                  sleep 100

[1] 是作业序号;
1810 是进程PID;
sleep 100 是命令;

命令 fg %

# 将作业[1]调度到前台终端运行
fg %1;

命令 bg %

# 将作业[1]调度到后台终端运行
bg %1;

命令 kill %

# 将作业[1]进程杀死
kill %1;

关于Linux 入门到放弃之七《进程管理》linux进程管理基础知识的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于boost:进程管理、CentOS中的网络管理+进程管理、CentOS基础:进程管理、Linux - 系统 - 进程管理等相关内容,可以在本站寻找。

本文标签: