当前位置: 首页 > article >正文

Linux:进程(一)

目录

一、概念的理解

二、指令(1)


一、概念的理解

        在许多地方对进程的定义都是这样的一句话:加载到内存中的程序、正在运行的程序、进程可以排队······

        而要真正理解进程是什么,这一句话的解释远远不够。

        在定义进程之前,先来理解程序,我们存储在计算机磁盘(当前,现在的设备多是固态硬盘,一个意思)的可运行程序是一个二进制文件,是要交给计算机的CPU来执行的,那么磁盘属于外设,根据冯诺依曼的计算机体系结构,外设不能直接和CPU传输数据,而是中间要经过内存

        那么,这个可运行程序就会加载到内存。

        那么,加载到内存以后,这就是进程了吗?


        事实上,我们可以同时启动多个程序,那么就意味着有多个程序被加载到内存。

        那么,操作系统必定要对这些加载到内存中的程序做管理

        而提到管理,必然离不开“先描述、再组织”,即先面向对象,再数据结构。

        于是,在一个程序加载到内存后,操作系统内核也会定义一个结构体变量跟踪管理这个程序。这个结构体变量称为进程控制块PCB(process control block),它内部包含这个进程的所有信息。

        Linux中描述PCB的结构体是task_struct


        因此,进程真正的理解为:

        (先描述,PCB是结构体,利用面向对象的思想)进程 = 内核PCB + 可执行程序

        (再组织,有了结构体,管理结构体利用数据结构)进程 = 内核数据结构(一般是链表) + 可执行程序。


        Linuxtask_struct结构体变量的内容大致分类:

标示符: 描述本进程的唯一标示符,用来区别其他进程。
状态: 任务状态,退出代码,退出信号等。
优先级: 相对于其他进程的优先级。
程序计数器: 程序中即将被执行的下一条指令的地址。
内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针。
上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。
I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。

        那么,我们作为用户,如何查看进程信息。这里有一个逻辑关系,PCB是内核结构体变量,属于操作系统内部变量,因此只能使用系统调用接口system call做相关操作。

二、指令(1)

  • 所有进程的目录
/proc/

        如果你想查看PID为1的进程信息,你可以查看下面这个目录

/proc/1
  • 打印进程的指令
ps axj

        psprocess的缩写,功能是显示当前系统的进程状态axj分别是-a、-x、-j三个参数。


        新建一个目录,比如24915,在该目录下新建源文件,同时配置Makefile文件。

[euto@VM-4-13-centos 24915]$ touch myprocess.c
[euto@VM-4-13-centos 24915]$ ls
myprocess.c
[euto@VM-4-13-centos 24915]$ ls > Makefile
[euto@VM-4-13-centos 24915]$ ls
Makefile  myprocess.c

        配置Makefile文件。

[euto@VM-4-13-centos 24915]$ cat Makefile 
myprocess:myprocess.c
	gcc -o $@ $^ -std=c99
.PHONY:clean
clean:
	rm -f myprocess

        编辑源文件。

[euto@VM-4-13-centos 24915]$ cat myprocess.c 
#include <stdio.h>
#include <unistd.h>

int main()
{
  while(1)
  {
    printf("i am a process!\n");
    sleep(1);
  }
  return 0;
}

        编译完成后,执行该程序。

[euto@VM-4-13-centos 24915]$ ./myprocess 
i am a process!
i am a process!
i am a process!
i am a process!
i am a process!
i am a process!
i am a process!
i am a process!
i am a process!
i am a process!
i am a process!
······

        同时,再观察进程信息。

[euto@VM-4-13-centos 24915]$ ps axj | head -1 && ps axj | grep myprocess
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
28701 15839 15839 28701 pts/1    28701 T     1001   0:00 ./myprocess
17253 20133 20132 17253 pts/2    20132 S+    1001   0:00 grep --color=auto myprocess
//打印的第二行是因为,grep本身也是可执行程序,即进程,在执行grep的时候
//这个可执行程序的参数带有myprocess的字眼
//可以使用grep 的 -v选项过滤掉这一行
[euto@VM-4-13-centos 24915]$ ps axj | head -1 && ps axj | grep myprocess | grep -v grep
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
28701 15839 15839 28701 pts/1    28701 T     1001   0:00 ./myprocess
  • 几乎所有的指令也是可执行程序,当执行指令操作后,也会成为进程

        下面,为了方便观察进程,让打印进程的指令做循环操作,不断检测进程状态。

//while true
//do
//   a
//   b
//   ···
//done
[euto@VM-4-13-centos 24915]$ while :; do ps ajx | head -1 && 
>ps ajx | grep myprocess | grep -v grep;
>sleep 1;
>done
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
················

        执行可执行程序myprocess后,观察到进程从无到有的过程:

[euto@VM-4-13-centos 24915]$ while :; do ps ajx | head -1 && ps ajx | grep myprocess | grep -v grep; sleep 1; done
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 2569  9385  9385  2569 pts/1     9385 S+    1001   0:00 ./myprocess
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 2569  9385  9385  2569 pts/1     9385 S+    1001   0:00 ./myprocess
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 2569  9385  9385  2569 pts/1     9385 S+    1001   0:00 ./myprocess
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 2569  9385  9385  2569 pts/1     9385 S+    1001   0:00 ./myprocess

        我们已经知道PCB属于内核数据,想要访问PCB需要系统调用接口system call。获取PID的命令名为getpid

//执行man getpid查看相关信息

GETPID(2)                  Linux Programmer's Manual                 GETPID(2)

NAME
       getpid, getppid - get process identification

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

       pid_t getpid(void);
       pid_t getppid(void);
··········

        结果显示getpid是2号手册的内容。

//执行man man查看手册的描述
       1   Executable programs or shell commands
       //2号手册描述系统调用接口的使用
       2   System calls (functions provided by the kernel)
       3   Library calls (functions within program libraries)
       4   Special files (usually found in /dev)
       5   File formats and conventions eg /etc/passwd
       6   Games
       7   Miscellaneous  (including  macro  packages  and  conventions), e.g.
           man(7), groff(7)
       8   System administration commands (usually only for root)
       9   Kernel routines [Non standard]

        修改源文件内容。

[euto@VM-4-13-centos 24915]$ cat myprocess.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
  pid_t id = getpid();
  while(1)
  {
    printf("i am a process! id: %d \n",id);
    sleep(1);
  }
  return 0;
}

        和原来一样的操作打印进程信息,观察进程从无到有的过程:

[euto@VM-4-13-centos 24915]$ while :; do ps ajx | head -1 && ps ajx | grep myprocess | grep -v grep; sleep 1; done
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 2569 18465 18465  2569 pts/1    18465 S+    1001   0:00 ./myprocess
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 2569 18465 18465  2569 pts/1    18465 S+    1001   0:00 ./myprocess

        程序运行结果显示:

i am a process! id: 18465 
i am a process! id: 18465 
i am a process! id: 18465 
i am a process! id: 18465 
·······

        一般在Linux中,普通进程都有父进程且唯一,而一个进程可能是多个子进程的父进程。

//查看getppid的使用方法
man getppid

        同上一个操作一样,修改源文件,观察进程信息。

[euto@VM-4-13-centos 24915]$ ./myprocess 
i am a process! id: 23894,fid: 2569 
i am a process! id: 23894,fid: 2569 
^C
[euto@VM-4-13-centos 24915]$ ./myprocess 
i am a process! id: 23982,fid: 2569 
i am a process! id: 23982,fid: 2569 
^C
[euto@VM-4-13-centos 24915]$ ./myprocess 
i am a process! id: 23992,fid: 2569 
i am a process! id: 23992,fid: 2569 
^C

        不难发现,普通进程,每次启动后,PID都是随机变化的,但是父进程是唯一不变的。但是进程2569到底是什么程序呢?

[euto@VM-4-13-centos 24915]$ ps ajx | head -1 && ps axj | grep 2569
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 2562  2569  2569  2569 pts/1     2569 Ss+   1001   0:00 -bash
 3778 26700 26699  3778 pts/2    26699 S+    1001   0:00 grep --color=auto 2569

        关于bash,bash是Shell的其中一种

        Shell 编程跟 JavaScript、php 编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。

        Linux 的 Shell 种类众多,常见的有:

  • Bourne Shell(/usr/bin/sh或/bin/sh)
  • Bourne Again Shell(/bin/bash)
  • C Shell(/usr/bin/csh)
  • K Shell(/usr/bin/ksh)
  • Shell for Root(/sbin/sh)

        Bash,也就是 Bourne Again Shell,由于易用和免费,Bash 在日常工作中被广泛使用。同时,Bash 也是大多数Linux 系统默认的 Shell。

        Bash即命令解释器,在命令行启动的程序,都是Bash的子进程。 


http://www.kler.cn/a/307572.html

相关文章:

  • linux c/c++最高效的计时方法
  • Electron 项目启动外部可执行文件的几种方式
  • openSUSE 环境下通过 zypper 安装软件
  • 类别变量分析——卡方独立性检验卡方拟合优度检验
  • VMware虚拟机安装Win7专业版保姆级教程(附镜像包)
  • 【STM32】基于SPI协议读写SD,详解!
  • 无人机建模详解!!!
  • [Leetcode LCR 154][Medium]-复杂链表的复制-链表
  • JSON数组
  • 通信工程学习:什么是接入网(AN)中的CF核心功能
  • dplyr、tidyverse和ggplot2初探
  • 一些学习three的小记录
  • RK3588九鼎创展方案在Arm集群服务器的项目中的应用分析​​
  • 关于决策树集成的一份介绍
  • IDEA 新版本设置菜单展开
  • Python 单元测试详解:Unittest 框架的应用与最佳实践
  • java.人机猜拳游戏
  • JVM 性能优化与调优-Shenandoah GC
  • [K8S]Forbidden: pod updates may not change fields other than
  • 【Linux】NAT
  • 医学数据分析实训 项目三 关联规则分析预备项目---购物车分析
  • Django——多apps目录情况下的app注册
  • 在Ubuntu 16.04上安装R的方法
  • 题目:单调栈
  • SpringBoot用kafka.listener监听接受Kafka消息
  • 基于SpringBoot+Vue+MySQL的美术馆管理系统