IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Linux下的进程 -> 正文阅读

[系统运维]Linux下的进程

一些问题

  1. 什么是进程?
    ??进程就是正在运行的程序, 是动态的. 是操作系统分配资源的最小单位.
  2. 什么是程序?
    ??程序是存储在存储介质上的经过编译的可执行二进制文件, 是静态的.
CPU
进程1
进程2
进程3

一些概念

时间片

时间片: cpu分配运行时间的单位, 它是CPU在进程上运行的前提.
CPU会保证每一个进程都会有一定数量的时间片, 轮巡地在各个进程之间切换.
由于CPU的运行速度非常快, 其轮巡的速度也远远在我们可以察觉的速度之上

进程ID

每个进程都有唯一的标识符,这个标识符就是进程ID。简称为“PID"。

进程A|进程B
——————
内核

??进程A与进程B之间交流的过程成为“进程间的通信”。进程并不能通过应用层直接交流,通过Linux内核进行交流。在内核中创造一个对象,利用对象进行交流。所以进程通信都是基于文件IO进行的。如通过open/close打开/关闭交流对象,通过read获取信息,通过write发送信息。
??像一些特殊的对象,如管道等,一般都使用文件IO进行而不是标准IO。

进程的三种基本状态

  1. 就绪态:除了CPU以外的其它资源全部准备好了。可以变成执行态,可以由执行态和阻塞态转变而来。
  2. 执行态:CPU正在处理执行这个进程。可以转变成阻塞态、就绪态,只能由就绪态转变而来。
  3. 阻塞态:进程再等待其他资源准备好。可以转变成就绪态,只能由执行态转变而来。

进程的控制:

进程的创建

fork函数:
头文件:unistd.h
函数原型:pid_t fork(void)
返回值:fork函数返回:

  1. 父进程中,返回子进程的PID
  2. 子进程中,返回0
  3. 出现错误,返回一个负值

??什么是父进程、子进程?进程1中创建了进程2,那么它们之间存在的创建于被创建的关系就是父子关系。也即进程1是进程2的父进程;进程2是进程1的子进程。

#include<stdio.h>
#include<unistd.h>

int main(void)
{
	pid_t pid;
	pid=fork();
	if(pid<0)
	{
		printf("process create failed!\n");
	}
	else if(pid == 0)
	{
		printf("This is child process!\n");
	}
	else
	{
		printf("This is parent process!Its child PID=%d\n",pid);
	}
	return 0;
}

??编译运行上述文件,根据PID的输出就可以判断进程创建是否成功、当前进程是子进程还是父进程。

获取进程的PID

函数:getpid()getppid()分别可以获取当前、父进程的PID。所以可以修改上面的c文件以获取子进程时的父进程以及自身PID,修改如下:

#include<stdio.h>
#include<unistd.h>

int main(void)
{
    pid_t pid;
    pid=fork();
    if(pid<0)
    {   
        printf("process create failed!");
    }   
    else if(pid == 0)
    {   
        printf("This is child process!");
        printf("PID=%d parent PID=%d\n",getpid(),getppid());
    }   
    else
    {   
        printf("This is parent process!");
        printf("PID=%d Its child PID=%d\n",getpid(),pid);
    }   
    return 0;
}
~ 

子进程中的父进程PID应该和父进程中的PID相同。测试上述文件结果如下:
在这里插入图片描述
为什么会输出两行结果?因为在创建进程之后,子进程在创建的位置复制父进程的资源后从fork语句下执行。与此同时父进程也继续从fork语句往下处理,所以打印出了两行结果:

fork
fork
父进程
父进程
子进程

父子进程的执行顺序

??父子进程的执行顺序是不定的,父子进程之间也是竞争CPU的。所以谁先抢占到CPU谁就先执行(父慈子孝),没有固定的谁先谁后。

ps命令和kill命令

ps命令

??ps命令可以列出系统中当前运行的那些进程。

Usage: ps [options]
	功能:用来显示当前进程的状态
	常用参数:
		aux 注意没有-符号
		a 显示关联终端所有进程(可以与用户进行交互的)
		u 显示进程的归属用户,相关内存的使用情况
		x 显示的a参数涉及的进程的补集(ax显示所有不关联终端的进程)
	To see every process on the system using BSD syntax:
		ps ax
		ps axu

在这里插入图片描述TTY是关联的终端。另外aux显示的进程太多了,如果我们需要特别地查找一些进程,该如何使用呢?这会在后面的管道中进行讲解,这里举一个例子(查找/usr/sbin/vmtoolsd相关的进程):

ps aux | grep /usr/sbin/vmtoolsd

kill命令

kill命令用来杀死进程

kill -9(SIGKILL) PID
	这里-9或者SIGKILL是一种“信号”
	可以用kill -l 查询总共有哪些信号
		在后面的信号通信中会进一步讲解

假设我们在当前路径下有一个./a.out进程,会一直循环无法退出。我们新开一个控制台,用如下命令查找进程的PID,并用kill命令杀死该进程:

ps aux | grep a.out

在这里插入图片描述这里的第一行就是我们循环的程序,第二列就是PID号(第一列被模糊处理了)3220。我们用kill命令杀死该进程:

kill -9 3220

在这里插入图片描述

孤儿进程和僵尸进程

孤儿进程:父进程结束以后,子进程还没有结束,这个子进程就叫做“孤儿进程”。
将是进程:子进程结束后,父进程还在运行且不去释放进程进程控制块,这个子进程就叫做“僵尸进程”

孤儿进程

孤儿进程会被PID为1的Init进程领养,也就是子进程的PPID变成1(对于Ubuntu系统,会用别的PID对应的进程作为Init进程)。我们可以做如下实验:

#include<unistd.h>
#include<stdio.h>

int main(void)
{
    pid_t pid;
    pid=fork();
    if(pid<0)
    {   
        printf("fork error!\n");
    }   
    else if(pid==0)
    {   
        printf("1st PPID=%d\n",getppid());
        sleep(5);//子进程先sleep 5秒,等待父进程结束
        printf("2nd PPID=%d\n",getppid());
    }   
    else
    {   
        printf("1st Father,PID=%d\n",getpid());
    }   
    return 0;
}

执行上述程序,结果如下:
在这里插入图片描述可以发现子进程最开始的PPID和最后的PPID并不相同,但是第二个PPID也不为1!我们查找一下这个进程:

ps aux | grep 868

在这里插入图片描述这也印证了Ubuntu系统的Init进程的PID是其他的进程(这里是systemd --user)。

僵尸进程

注意:父进程要没有时间去释放进程控制块(父进程的作用之一就是释放子进程的相关资源,这就是为什么孤儿进程需要被领养),子进程才是僵尸进程。
我们做如下实验:

#include<unistd.h>
#include<stdio.h>
int main(void)
{
    pid_t pid;
    pid=fork();
    if(pid<0)
    {   
        printf("fork error!\n");
    }   
    else if(pid>0)
    {   
        while(1);//让父进程一直运行,没有时间去释放进程控制块。
    }   
    else
    {   
        printf("this is child proc\n");
    }   
    return 0;
}

结果自然是卡死状态,我们使用ps命令查找相关进程如下:
在这里插入图片描述第一行是正在运行的父进程,他的状态是R+(运行);第二行是子进程,它的状态是Z+(僵尸),后面的<defunct>表示失灵的,死的。
我们可以使用kill命令杀死正在运行父进程,子进程就变成了

进程间的通信的几种方法

管道通信

信号通信

包括信号的发送、接收、处理

IPC通信

包括共享内存,消息队列,信号灯

socket通信

网络编程,出在同一个网络下的两个进程之间的通信

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-11-28 11:39:26  更:2021-11-28 11:40:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 2:37:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码