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、fork函数:

可以在代码中创建一个子进程。

pid_t fork(void)

  • a. 没有参数
  • b. pid_t:·本质是整形
  • c. 原理:fork创建的子进程的PCB拷贝父进程的PCB
  • d. 返回值:
    创建失败:-1
    创建成功:>0(子进程的PID号):返回给父进程
    =0:返回给子进程

注意:

  • 子进程是拷贝父进程的PCB的,子进程的大部分数据来源于父进程,例如:内存指针(数据段、代码段)
  • 父进程创建子进程成功之后,父子进程是两个独立的进程(进程的独立性),父子进程的调度取决于操作系统内核
  • 进程是抢占式执行的,父子进程谁先运行是不能确定的
  • 写时拷贝:写时拷贝是一种可以推迟甚至免除拷贝数据的技术。 内核此时并不复制整个进程地址空间,而是让父进程和子进程共享同一个拷贝。 只有在需要写入的时候,数据才会被复制,从而使各个进程拥有各自的拷贝。 也就是说, 资源的复制只有在需要写入的时候才进行 ,在此之前,只是以只读方式共享。

2、vfork函数:

父进程与子进程的内存指针指向同一块进程虚拟地址空间
调用方法:与fork函数完全相同
在这里插入图片描述

  • vfork函数调用栈混乱的问题:子进程调用函数不出栈,则父进程调用函数也出不了栈
  • 解决方法:子进程先调用,子进程调用完毕之后,父进程再调用

二、进程终止

  • 进程终止的方法:
    1、从main函数的return返回
    2、exit函数
    3、_exit函数

exit函数是库函数,在调用时会刷新缓冲区;
而_exit函数是库函数,在调用时不会刷新缓冲区。

在这里插入图片描述

三、进程等待

1、进程等待的作用:

父进程进行进程等待,子进程在先于父进程退出之后,由于父进程在等待子进程,所以父进程会回收子进程的退出资源,从而防止子进程产生僵尸进程。

2、wait函数:

pid_t wait(int *status)

  • 返回值:成功返回子进程的pid号;失败返回-1
  • 参数:整形指针,4个字节中只使用到2个字节。在这2个字节中,前8个比特位为进程退出码,中间一位为coredump标志位,后7位为终止信号。
    见下图:
    在这里插入图片描述

coredump标志位:
取值为1:表示当前的进程是由coredump(核心转储文件)产生
取值为0:表示当前进程没有coredump产生

终止信号:当前程序是由什么信号导致的终止

在这里插入图片描述

参数int *status是一个出参:
调用者准备一个int型的变量,将地址传给wait函数,wait函数在自己实现的内部进行赋值,当wait函数返回后,调用者就可以通过int变量,获取进程退出的信息。

下面对wait函数进行测试,看调用wait函数之后,子进程是否还会产生僵尸进程:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>
 
int main()
{
    pid_t pid=fork();                                                                                                                   
    if(pid<0)
    {
        printf("create process failed\n");
         return 0;
    }
    else if(pid==0)
    {
    	//子进程
    	//进程终止
        printf("i am child, %d-%d\n", getpid(), getppid());
        exit(1);
    }
    else
    {
    	//父进程
    	//进程等待
        int status;
        wait(&status);
        while(1)
		{
            printf("i am father, %d-%d\n", getpid(), getppid());
            sleep(1);
        }
    }
    return 0;
}

运行结果如下:
在这里插入图片描述
在这里插入图片描述
我们在输入子进程的PID号后发现子进程并未产生僵尸进程。

那么如何确定子进程是因为父进程进程等待而未产生僵尸进程还是因为在父进程退出后被1号进程所领养而未产生僵尸进程呢?

我们将代码进行修改,在子进程的代码中加入while循环,使子进程不结束,观察父进程是否退出,如父进程仍在运行,则说明是wait函数使子进程未产生僵尸进程。

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>
 
int main()
{
    pid_t pid=fork();                                                                                                                   
    if(pid<0)
    {
        printf("create process failed\n");
         return 0;
    }
    else if(pid==0)
    {
    	//子进程
    	//进程终止
        printf("i am child, %d-%d\n", getpid(), getppid());
        while(1)
        {
            sleep(1);
        }
        exit(1);
    }
    else
    {
    	//父进程
    	//进程等待
        int status;
        wait(&status);
    
    }
    return 0;
}

代码运行结果如下:
在这里插入图片描述
在这里插入图片描述
通过上图可以发现,在子进程未退出时,父进程由于调用wait函数仍在运行,从而验证得到是wait函数使子进程未产生僵尸进程。我们称这个现象为阻塞。

阻塞:当前执行流调用某一个函数的时候,该函数一直不返回,称这个现象为阻塞。

3、waitpid函数:

pid_t waitpid(pid_t pid,int *status,int options)

  • 返回值:
  • 当没有等待到相应的子进程,返回值为0
  • 等待到相应的子进程,返回值为等待到的进程的PID号(大于0)
  • 参数:
  • pid:
    ① 等于-1:等待任意子进程,一旦等待到了,则返回
    ② 大于0:等待特定的子进程,大于0的值,就是子进程的PID号
  • status:出参,同wait函数
  • options:
    ① WNOHANG:非阻塞等待方式(需要搭配循环去使用,直到完成函数功能)
    ② 0:阻塞等待方式

用代码实现waitpid函数:

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<unistd.h>
  4 #include<sys/wait.h>                                                                                                                    
  5 
  6 int main()
  7 {
  8     pid_t pid = fork();
  9     if(pid < 0)
 10     {
 11         perror("fork");
 12         return 0;
 13      }
 14      else if(pid == 0)
 15      {
 16         printf("i am child, pid is %d, ppid is %d\n", getpid(), getppid());
 17         sleep(5);
 18         exit(1);
 19       }
 20      else
 21      {
 22          pid_t ret = 0;
 23          do
 24          {
 25              ret = waitpid(-1, NULL, WNOHANG);
 26          }while(ret == 0);
 27       sleep(20);
 28       printf("i am father, pid is %d\n, exit...", getpid());
 29      }
 30 }

四、进程程序替换

1、作用:将正在运行的进程,替换成另外一个程序,运行另外一个程序的代码。

2、原理:将进程的代码段和数据段替换成为新的程序的代码和数据,更新堆栈信息。
在这里插入图片描述
3、应用场景:
①守护进程
②bash(命令行解释器)

4、接口: exec接口簇

int execl(const char *path, const char *arg, …);

  • 返回值:
  • 替换成功之后,该函数没有返回值,也不知道返回值该返回给谁。
  • 替换失败之后,才会有返回值,返回值小于0。
  • 参数:
  • path:带路径的可执行程序
  • arg:给待要替换的可执行程序传递参数(第一个参数是可执行程序本身;多个可执行参数,使用“,”间隔;参数的最后要以NULL结尾)
  • …:可变参数列表

int execlp(const char *file, const char *arg,…);

  • 参数:
  • arg:同execl
  • file:待替换的可执行程序
    注意: 如果只传递可执行程序的名称,则该可执行程序一定要在环境变量PATH中找到。或者也可以将待替换的可执行程序路径写全。

int execle(const char *path, const char *arg, …, char * const envp[]);

  • 参数:
  • path:带路径的可执行程序
  • arg:同execl
  • envp:指针数组,数组的每一个元素都是char*,程序员需要自己组织环境变量,放到envp指针数组中,最后一个元素需要放入NULL

int execv(const char *path, char const *argv[]);

  • 参数:
  • path:带路径的可执行程序
  • argv:指针数组,命令行参数的数组,存放的是传递给可执行程序的命令行参数(第一个参数是可执行程序本身,参数的最后要以NULL结尾)

总结:①函数名称带有“p”,则表示当前函数会自动搜索环境变量PATH ②函数名称带有“e”,则表示当前函数需要自己组织环境变量,放到envp指针数组中,以NULL结尾 ③函数名称带有“l”,则表示给待替换的可执行程序传递的命令行参数为可变参数列表 ④函数名称带有“v”,表示给待替换的可执行程序传递的命令行参数为指针数组

在这里插入图片描述

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-08-11 12:50:23  更:2021-08-11 12:51:34 
 
开发: 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年12日历 -2024/12/28 4:43:05-

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