linux 进程重要知识(详讲)

2023-11-02 03:08

本文主要是介绍linux 进程重要知识(详讲),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、进程基础

1.进程相关概念

  •   进程是一个独立可调度的任务,进程是一个抽象的实体,当系统在执行某个程序时,分    配和释放的各种的资源

  •   进程是一个程序的一次执行的过程

  •   进程是程序执行资源管理的最小单位

  •   进程和程序的区别:进程是动态的概念,它是程序执行的过程,包括创建、调度和消亡

                                   程序是静态的,它是一些保存在磁盘上的指令的有序集合,没有                                       任何执行的概念

                                                 正文段(.test)

                                进程         用户数据段(.data)     程序

                                                系统数据段 

         进程不仅包括程序的指令和数据,而且包括程序计数器值,CPU的所有寄存器以及存储临时数据的进程堆栈

2.linux下的进程结构

    主要的进程标识:进程号(Process Identity Number , PID)

                                父进程号(Parent Process ID,  PPID)

   Linux中的进程包含三个段:

  • 数据段:存放的是全局变量、常量以及动态数据分配的数据空间(如malloc函数取得的空间)等

  • 正文段:存放的是程序中的代码

  • 堆栈段:存放的是函数的返回地址、函数的参数以及程序中的局部变量

3.linux系统的进程类型

  • 交互进程:该进程是由shell控制和运行的。交互进程既可以在前台使用,也可以在后台使用

  • 批处理进程:该进程不属于某个终端,它被提交到一个队列中以便顺序执行

  • 守护进程:该类进程实在后台运行,它一般在linux启动时开始执行,系统关闭时才结束。

4.进程运行状态

  • 运行态(R):此时进程正在运行或者正在准备运行

  • 等待态:此时进程正在等待某一个事件的发生或者某种系统资源(阻塞,休眠,等待,睡眠态)           

              可中断态(S):接收到信号有反应          

              不可中断态(D):接收到信号没有反应

  • 停止态(T):此时进程已经被终止(SIGSTOP信号,SIGCONT信号)

  • 死亡态(Z):这是一个已终止的进程,但还在进程向量数组汇总占有一个task_struct结构体(僵尸态)

进程状态图:

                              

5.进程的模式

  进程的执行模式分为用户模式和内核模式

在系统中,有一个定时器,每隔1ms产生一次中断,中断会进入内核(成为心跳,滴答tick);在用户模式与内核模式切换时,只有发生中断,才能从用户模式进入到内核模式,系统调用都是靠软件进行中断,

6.调度进程

  • ps          查看系统中的进程

  • top        动态显示系统中的进程

  • nice      按用户指定的优先级运行进程

  • renice   改变正在运行的进程的优先级

  • kill         结束进程(包括后台进程)

  • bg          将挂起的进程在后台运行

  • fg           把后台的运行的进程放到前台运行

二、进程系统调用

1.进程创建:fock() 产生一个进程

       头文件:#include<sys/types.h>//提供类型pid_t的定义   #include <unistd.h>

      函数原型:pid_t fock(void);

      函数返回值:0:子进程,从fock返回的地方开始执行

                            子进程PID(大于零的证书):父进程

                            -1:出错

      getpid():获取pid号,子进程号

      getppid():获取ppid号,父进程号

孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。(系统启动首先要运行init进程,init扫描孤儿进程,收养孤儿进程)

僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程,通常是由父进程清理子进程的僵尸。

2.exec函数族(替换一个进程的映像)

 fock函数用于创建一个进程,该子进程几乎拷贝了父进程的全部内容

 exec函数族提供了一种在进程中启动另一个程序执行的方法。它可以根据指定的文件名或者目录名找到可执行文件,并用它来取代原调用进程的数据段、代码段、堆栈段。在执行完之后,原调用进程的内容除了进程号外,其他全部都被替换了。

什么时候使用?

 当进程认为自己不能在为系统和用户做出任何贡献了时就可以调用exec函数,让自己执行新的程序。如果某个进程想同时执行另一个程序,它就可以调用fock函数创建子进程,然后在子进程中调用任何一个exec函数。这样看起来就好像通过执行应用程序而产生了一个新进程一样。

      #include <unistd.h>

  •  int execl(const char *path, const char *arg, ... /* (char  *) NULL */);

  •  int execlp(const char *file, const char *arg, .../* (char  *) NULL */);

  •  int execle(const char *path, const char *arg, ... /*, (char *) NULL, char * const                                                                     envp[] */);

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

  •  int execvp(const char *file, char *const argv[]);

  •  int execvpe(const char *file, char *const argv[],char *const envp[]);

exec函数组使用区别:

  • 可执行文件查找方式

  • 参数表传递方式

  • 环境变量的使用

exec函数族使用注意点:

在使用exec函数族时,一定要加上错误判断语句

常见的错误原因有:

  • 找不到文件或者路径,此时errno被设置为ENOENT

  • 数组argy和envp忘记用NULL结束,此时errno被设置为EFAULT

  • 没有对应可执行的的运行权限,此时ERRNO被设置EACESS

3.exit 和 _exit

头文件: exit:#include<stdlib.h> 

               _exit: #include <unistd.h>

函数原型: exit:  void exit(int status);

               _exit:void  _exit(int status);

函数传入值:status是一个证书的参数,可以利用这个参数传递进程结束时的状态,通常()表示正常结束;其他的数值表示出现了错误,进程非正常结束。在实际编程时,可以用wait系统调用接受子进程的返回值,进程相应的处理

_exit和exit的区别:

  • _exit()函数的作用最为简单:直接使进程终止结运行,清除其使用的内存空间,并销毁其在内核中的数据结构

  • exit()函数则在这些基础上做了一些包装,在执行退出之前加了若干道工序

  • exit()函数在调用exit系统调用之前要文件的打开情况,把文件缓冲区中的内容写入文件,就是图中的“清理I/O缓冲”一项

                           

4.wait 和 waitpid

  • wait函数:调用该函数使进程阻塞,直到任一个子进程结束或者是该进程接受到了一个信号为止(等待态,可中断)。如果该进程没有子进程或者其子进程已经结束,wait函数会立即返回。

  • waitpid函数:功能和wait函数类似。不同的是可以指定某一子进程结束以及等待的方式(阻塞或非阻塞)

wait()函数

头文件  #include<sys/types.h>

             #include <sys/wait.h>

函数原型:   pid_t wait(int *status);

函数参数:   status是一个整形指针,指向的对象用来保存子进程退出时的状态。

  •                      status若为空,表示忽略子进程退出时的状态

  •                      status若不为空,表示保存子进程退出时的状态

  •                       另外,子进程的结束状态可由linux中一些特定的宏来测定

waitpid()函数

头文件  #include<sys/types.h>

             #include <sys/wait.h>

函数原型:pid_t waitpid(pid_t pid, int *status, int options)

函数参数:pid

  • pid>0:只等待进程ID等于pid的子进程,不管已经有其他子进程运行结                                   束退出了,只要指定的子进程还没 有结束,waitpid就会一直等下去

  • pid =1: 等待任何一个子进程退出,此时和wait作用一样

  •  pid =0:等待其他组ID等于调用进程的组ID的任一子进程

  •  pid<0:  等待七组ID等于pid的绝对值的任一进程

  status:获取子进程结束信息

 options

  • WNOHOG,若由pid指定的子进程并不立即只使用,到waitpid不阻塞,此时返回值为0

  •  WUNTRACED:若某实现支持作业控制,则由pid指定的任一子进程已暂停,且其状态自暂停以来还来报告过,则返回其状态

  •   0:同wait,苏泽父进程,等待子进程退出

函数返回值:正常:结束的子进程的进程号

                     使用选项WNOHANG且没有子进程结束时:0

                     调用出错:-1

   5.linux守护进程

  • 守护进程,也就是通常所说的Daemon进程,是linux中的后台服务进程,它是一个生存期较长的进程,通常独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件

  • 守护进程常常在系统启动时开始运行,在系统关闭时终止

  • linux系统有很多守护进程,大多数服务都是用守护进程实现的          

  • 在linux中,每一个系统与用户进行交流的界面称为终端。从该终端开始运行的进程都会依附于这个终端,这个终端称为这些进程的控制终端,当控制终端被关闭时,相应的进程都会被自动关闭。

  • 守护进程能够突破这种限制,他从开始运行,直到整个系统关闭才会退出。如果让某个进程不会因为用户或者终端的变化而受到影响,就必须把这个进程变成一个守护进程。

6.linux守护进程编写步骤

(1) 创建子进程,父进程退出

 第一步需要子进程在形式上做到与控制终端的脱离,由于父进程已经先于子进程退出, 子进程编程孤儿进程

pid=fork();
if(pid>0)
{exit(0);
}

(2)在子进程中创建新会话

进程组是一个或多个进程的集合。进程组由进程组ID来唯一表示,每个进程组都有一个组长进程,进程组ID就是组长进程的进程号;

会话期是一个或多个进程组的集合

setsid();

(3)改变当前目录为根目录

通常的做法是让“/”或“/tmp”作为守护进程的当前工作目录

在进程运行过程中,当前目录所在的文件系统时不能卸载的

chdir函数可以改变进程当前工作目录

chdir("/");

(4)重设文件权限掩码

文件权限掩码是指文件权限中被屏蔽掉的对应位把文件权限掩码设置为0,可以增加该守护进程的灵活性。

umask(0);

(5)关闭文件描述符

新建的子进程会从父进程那里继承所有已经打开的文件,在创建新的会话后,该守护进程已经脱离任何控制终端,应当关闭用不到的文件。(一般情况下只需要关闭系统自带的三个文件描述符就行),如果在这里需要打印调试,“先不脱离,关闭”。

close(0);
close(1);
close(2);

                        

 

 

 

 

 

 

 

 

 

 

 

 

 

 

这篇关于linux 进程重要知识(详讲)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/327665

相关文章

Linux磁盘分区、格式化和挂载方式

《Linux磁盘分区、格式化和挂载方式》本文详细介绍了Linux系统中磁盘分区、格式化和挂载的基本操作步骤和命令,包括MBR和GPT分区表的区别、fdisk和gdisk命令的使用、常见的文件系统格式以... 目录一、磁盘分区表分类二、fdisk命令创建分区1、交互式的命令2、分区主分区3、创建扩展分区,然后

Linux中chmod权限设置方式

《Linux中chmod权限设置方式》本文介绍了Linux系统中文件和目录权限的设置方法,包括chmod、chown和chgrp命令的使用,以及权限模式和符号模式的详细说明,通过这些命令,用户可以灵活... 目录设置基本权限命令:chmod1、权限介绍2、chmod命令常见用法和示例3、文件权限详解4、ch

Linux内核之内核裁剪详解

《Linux内核之内核裁剪详解》Linux内核裁剪是通过移除不必要的功能和模块,调整配置参数来优化内核,以满足特定需求,裁剪的方法包括使用配置选项、模块化设计和优化配置参数,图形裁剪工具如makeme... 目录简介一、 裁剪的原因二、裁剪的方法三、图形裁剪工具四、操作说明五、make menuconfig

Linux使用nohup命令在后台运行脚本

《Linux使用nohup命令在后台运行脚本》在Linux或类Unix系统中,后台运行脚本是一项非常实用的技能,尤其适用于需要长时间运行的任务或服务,本文我们来看看如何使用nohup命令在后台... 目录nohup 命令简介基本用法输出重定向& 符号的作用后台进程的特点注意事项实际应用场景长时间运行的任务服

什么是cron? Linux系统下Cron定时任务使用指南

《什么是cron?Linux系统下Cron定时任务使用指南》在日常的Linux系统管理和维护中,定时执行任务是非常常见的需求,你可能需要每天执行备份任务、清理系统日志或运行特定的脚本,而不想每天... 在管理 linux 服务器的过程中,总有一些任务需要我们定期或重复执行。就比如备份任务,通常会选在服务器资

如何评价Ubuntu 24.04 LTS? Ubuntu 24.04 LTS新功能亮点和重要变化

《如何评价Ubuntu24.04LTS?Ubuntu24.04LTS新功能亮点和重要变化》Ubuntu24.04LTS即将发布,带来一系列提升用户体验的显著功能,本文深入探讨了该版本的亮... Ubuntu 24.04 LTS,代号 Noble NumBAT,正式发布下载!如果你在使用 Ubuntu 23.

Linux限制ip访问的解决方案

《Linux限制ip访问的解决方案》为了修复安全扫描中发现的漏洞,我们需要对某些服务设置访问限制,具体来说,就是要确保只有指定的内部IP地址能够访问这些服务,所以本文给大家介绍了Linux限制ip访问... 目录背景:解决方案:使用Firewalld防火墙规则验证方法深度了解防火墙逻辑应用场景与扩展背景:

Linux下MySQL8.0.26安装教程

《Linux下MySQL8.0.26安装教程》文章详细介绍了如何在Linux系统上安装和配置MySQL,包括下载、解压、安装依赖、启动服务、获取默认密码、设置密码、支持远程登录以及创建表,感兴趣的朋友... 目录1.找到官网下载位置1.访问mysql存档2.下载社区版3.百度网盘中2.linux安装配置1.

C#如何优雅地取消进程的执行之Cancellation详解

《C#如何优雅地取消进程的执行之Cancellation详解》本文介绍了.NET框架中的取消协作模型,包括CancellationToken的使用、取消请求的发送和接收、以及如何处理取消事件... 目录概述与取消线程相关的类型代码举例操作取消vs对象取消监听并响应取消请求轮询监听通过回调注册进行监听使用Wa

Linux使用粘滞位 (t-bit)共享文件的方法教程

《Linux使用粘滞位(t-bit)共享文件的方法教程》在Linux系统中,共享文件是日常管理和协作中的常见任务,而粘滞位(StickyBit或t-bit)是实现共享目录安全性的重要工具之一,本文将... 目录文件共享的常见场景基础概念linux 文件权限粘滞位 (Sticky Bit)设置共享目录并配置粘