首页 > 系统相关 >进程的基本概念

进程的基本概念

时间:2023-08-11 20:00:47浏览次数:38  
标签:status const 函数 int char 进程 基本概念

一、进程的基本概念
1、进程与程序
程序是存储在磁盘上的可执行文件,程序被加载到内存中开始运行称为进程,一个程序可以同时加载成多个进程,进程就是处于活动状态下的程序
2、进程的分类
进程根据功能不同一般分为三种类型:交互进程、批处理进程、守护进程
交互进程:由一个shell终端启动的进程,在运行过程中需要与用户进行交互操作,可以运行于前台,也可以在后台运行
批处理进程:该进程是一个进程的集合,负责按顺序执行预定义好的操作
守护进程:一般处于活跃状态,运行在后台,一般都是由系统在开机时通过启动系统脚本自动创建
3、查看进程
简单形式:ps 显示当前用户有控制终端的进程简单信息
列表形式:ps -auxw 以最大列宽显示所有进程的详细信息
USER 进程的属主
PID 进程的编号
%CPU CPU的使用率
%MEM 内存的使用率
VSZ 虚拟内存使用的字节数
RSS 物理内存使用的字节数
TTY 终端设备号 ?表示无终端控制
STAT 进程的状态
O 就绪态 等待被调度
R 运行态 Linux没有O,就绪也用R表示
S 可被唤醒的睡眠态,例如系统中断、获得资源、收到信号都可以唤醒进入R
D 不可被唤醒的睡眠态,只能被系统唤醒
T 暂停态 收到SIGSTOP转入T,收到SIGCONT转入R
Z 僵尸态
X 死亡状态
< 高优先级
N 低优先级
s 进程组中的领导者
l 多线程的进程
+ 处于后台的进程组
START TIME 进程运行总时间
COMMAND 进程的启动命令
4、父进程、子进程、孤儿进程、僵尸进程
一个进程可以被另一个进程创建,创建者称为被创建者的父进程,被创建者称为创建者的子进程,当子进程被父进程创建启动后在操作系统的调度下同时运行
当子进程先于父进程结束时,子进程会向父进程发送SIGCHLD信号,此时父进程应该去回收子进程的相关资源,如果父进程没有去回收子进程,那么子进程变成了僵尸进程
父进程先于子进程结束,子进程就变成孤儿进程,所有的孤儿进程都会被系统指定的一个进程领养(1 /sbin/init)接管,该进程就变成了孤儿进程的父进程
5、进程标识符 pid_t
每个进程都有一个以非负整数表示的唯一标识,即进程ID\PID
进程ID在任意时刻中都是唯一的,但是可以重用,进程一旦结束它的进程ID会被系统回收,过一段时间后,可以继续分配给新的进程(延时重用)
pid_t getpid(void);
功能:获取调用者的进程ID
pid_t getppid(void);
功能:获取调用者父进程的进程ID

二、进程的创建
pid_t fork(void);
功能:创建一个子进程
返回值:成功时一次调用两次返回,子进程返回0,父进程返回的是子进程的pid
当进程的数量超过系统的限制可能会创建失败返回一次-1
注意:
1、子进程创建成功后,会与父进程同样从fork处开始继续往下执行,为了让父子进程分别执行不同的功能,可以通过返回值的不同让它们进入不同的分支语句
2、通过fork创建的子进程会拷贝父进程的数据段、bss段、堆、栈、I/O流缓冲区等数据,与父进程共享代码段的数据,子进程会继承父进程的信号处理方式
3、fork结束后,不确定是父进程先返回还是子进程先返回,可以通过休眠函数来让另一个进程先执行
4、通过fork创建的子进程可以共享父进程的文件描述符
练习1:通过fork创建4个子进程,再为这4个子进程各自创建2个子进程

pid_t vfork(void);
功能:以加载可执行程序的方式创建并运行子进程
返回值:成功子进程返回0 父进程返回子进程pid
注意:
1、子进程一定先返回,此时子进程不算完全创建成功,需要加载一个可执行程序来替换当前子进程的所有资源,替换完成后子进程才算完全的创建成功,此时父进程才会返回

使用exec系列函数让子进程加载可执行程序
int execl(const char *path, const char *arg, ...
                   /* (char  *) NULL */);
path:要加载的可执行文件的路径
arg:命令行参数 最后一个一定要以NULL结尾
int execlp(const char *file, const char *arg, ...
                /* (char  *) NULL */);
file:要加载的可执行文件的名字,会根据PATH环境变量中记录的路径查找并加载该文件
注意:如果想要指定一个路径,那么需要在配置文件中增加PATH的值

int execle(const char *path, const char *arg, ...
                /*, (char *) NULL, char * const envp[] */);
path:要加载的可执行文件的路径
arg:命令行参数 最后一个一定要以NULL结尾
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[]);

注意:
1、exec系列函数成功不返回,失败才会返回-1
2、以vfork、exec函数创建出来的子进程不会继承父进程的信号处理方式,但是能继承父进程的信号屏蔽集

考点:对比fork和vfork区别?
    1.  fork(): 子进程拷贝父进程的数据段,代码段
        vfork(): 子进程与父进程共享数据段
    2.  fork(): 父子进程执行次序不确定
        vfork(): 保证子进程先运行,在调用exec()或exit()之前,与父进程数据共享,在exec()或exit()调用之后,父进程才能运行
    3. 在使用vfork函数在调用exec()或exit()之前,子进程依赖于父进程的进一步动作,将会导致死锁

int system(const char *command);
功能:创建子进程加载command程序来执行系统命令

三、进程的正常退出
1、执行了main函数的return n语句,该返回值可以被父进程接收到
2、进程调用了exit函数,该函数是属于C标准库提供的
void exit(int status);
功能:能在任意时候结束进程
status:结束状态码EXIT_SUCCESS\EXIT_FAILURE,效果与main函数return 的值等同
注意:该函数不会返回
int atexit(void (*function)(void));
功能:向内核注册绑定一个进程结束前要执行的函数

    int on_exit(void (*function)(int,void *),void *arg);
    功能:向内核注册绑定一个进程结束前要执行的函数   
    arg:会在调用function的时候传递给该函数

    进程正常退出前要完成步骤:
    1、先调用atexit\on_exit函数进行注册的函数,如果注册多个函数,结束时这些函数的执行顺序与注册顺序相反
    2、冲刷并关闭所有打开状态下的标准IO流
    3、调用_exit\_Exit函数

3、调用_exit\_Exit函数
    void _exit(int status);
    功能:结束进程,由系统提供
    void _Exit(int status);
    功能:结束进程,由标准库提供
    1、它们的参数status会被父进程获取到
    2、结束前会关闭所有打开状态下的系统IO的文件描述符
    3、向父进程发出结束信号SIGCHLD
    4、该函数不会返回
4、进程的最后一个线程执行了return返回语句
5、进程的最后一个线程执行了pthread_exit函数

四、进程的异常终止
1、进程调用了abort函数,产生了SIGABRT信号
2、进程接收到了其他进程的某些信号,导致终止
3、进程自己的错误操作导致终止,例如:段错误、除零等
4、进程的最后一个线程接收到了"取消"请求操作,并响应了请求
注意:以上的异常终止方式,都会让父进程无法获取结束进程的结束状态码,所以才叫异常终止
注意:无论进程是如何结束的,他们的资源都会被回收,所有的文件描述符、文件指针都会被关闭

五、子进程的回收
对于任何结束方式,都希望父进程能够获取到,通过wait、waitpid函数可以知道子进程是如何结束的以及结束状态码
pid_t wait(int *status);
功能:等待任意子进程的结束,并获取其结束状态码
status:输出型参数
返回值:子进程的ID
1、如果所有子进程都还运行,则阻塞等待
2、如果有一个子进程结束,立即返回该进程的结束状态码和pid
3、如果没有子进程运行,立即返回-1
WIFEXITED(status)
判断子进程是否是正常退出,如果是返回真
WEXITSTATUS(status)
如果子进程是正常退出的,可以获取正确的结束状态码,只获取低八位
WIFSIGNALED(status)
判断子进程是否是异常退出,如果是返回真
WTERMSIG(status)
如果子进程是异常退出的,可以获取杀该子进程的信号id

pid_t waitpid(pid_t pid, int *status, int options);
功能:指定回收某个或者某些子进程的状态
pid:
    <-1     等待组id为abs(pid)的进程组中的任意子进程结束
    -1      等待任意子进程结束 功能与wait等同
    0       等待调用者同组的任意子进程结束
    >0      等待该进程结束
status:处理与wait等同
options:等待模式
    0       正常的阻塞模式 等同wait
    WNOHANG 非阻塞模式 如果没有子进程结束,立即返回0
    WUNTRACED 如果等待的子进程中有处于暂停态的,立即返回该子进程的状态码
    WCONTINUED 如果等待的子进程中有从暂停态转入为运行的,立即返回该子进程的状态码

    用于判断和获取status的宏函数:
    WIFSTOPPED 判断状态码,如果子进程是转入暂停态,返回真
    WSTOPSIG   当子进程是暂停态返回时,获取导致暂停态的信号id
    WIFCONTINUED 判断状态码,如果子进程是由暂停态转入运行态,返回真

注意:
1、如果没有子进程结束 wait会阻塞等待,如果在父进程的业务逻辑代码出wait,会对父进程的业务产生阻塞影响,因为子进程结束时会给父进程发送SIGCHLD信号,可以通过在父进程中注册该信号处理函数,在该函数内执行wait,就不影响父进程的业务执行,但是信号最好选择可靠信号
2、waitpid可以选择不阻塞等待,因此不需要像wait一样在信号处理函数中执行,可以直接在父进程的业务逻辑中调用不受影响

标签:status,const,函数,int,char,进程,基本概念
From: https://www.cnblogs.com/wangqiuji/p/17623845.html

相关文章

  • python多进程运行
    多进程并行的模块:multiprocessingultiprocessing包的详解需要涉及到以下几个方面:进程类(Process):这是multiprocessing包的核心类,它用于创建和管理一个进程。进程类接受一个target参数,指定要在进程中执行的函数,以及一个args参数,指定要传递给函数的参数。进程类还有一些方法和属性,......
  • 进程间通信的6种方式
    1、管道:1)管道传输数据是单向的,如果想相互通信,需要建立两个管道。2)管道这种通信方式效率低,不适合进程间频繁地交换数据。3)优点是简单,很容易得知管道里的数据已经被另一个进程读取了。 2、消息队列:1)消息队列是保存在内核中的消息链表,AB进程互相发送消息,只要把数据放在消息队......
  • 进程 线程 协程的区别
    进程进程是操作系统,进行资源分配和调度的基本单位,多个进程之间相互独立,进程的特点是稳定性好,如果一个进程崩溃,不影响其他进程,但是进程消耗资源大,开启的进程数量有限制线程线程是cpu进行资源分配和调度的基本单位,线程是进程的一部分,是比进程更小的,能独立运......
  • 【Linux】进程优先级 | 进程的切换 | 环境变量详解
      ......
  • 如何利用PowerShell来监控一个进程中的线程数
    如何利用PowerShell来监控一个进程实际产生了多少个线程$processName="chrome.exe"$process=Get-WmiObject-Query"SELECT*FROMWin32_ProcessWHEREName='$processName'"$threadCount=$process.ThreadCountWrite-Host"Thenumberofthreadsin......
  • Android13冻结进程分析:如何提高设备性能和用户体验
    Android13冻结进程分析:如何提高设备性能和用户体验本文介绍了Android13中的冻结进程功能,它是一种重要的资源管理策略,可以提高系统性能和稳定性,同时最大限度地节省设备的资源和电池消耗。文章讨论了如何合理分配资源,包括CPU、内存等,以提高设备性能和用户体验。此外,文章还提到了......
  • 云存储---ceph简介架构原理和一些基本概念
    Ceph简介Ceph是一个分布式存储系统,提供对象,块和文件存储,是一个免费开源软件的存储解决方案,可以部署于普通的x86兼容服务器上,可用于解决统一存储的io问题。Ceph诞生于2004年,最早是SageWeil一项关于存储系统的PhD研究项目,致力于开发下一代高性能分布式文件系统的项目。随着云计算的发......
  • 云计算云存储的一些基本概念
    我们在学习云计算和云存储之前,需要先了解一些很常见的基本概念,否则在学习过程中和选型时会比较晕。云计算的三种服务模式:IaaS,PaaS和SaaS云的分层任何一个在互联网上提供其服务的公司都可以叫做云计算公司。其实云计算分几层的,分别是Infrastructure(基础设施)-as-a-Service,Platform(平......
  • 怎么判断linux中的内核进程与用户进程
    在ubuntu或者centos中,1号init进程或者systemd为用户进程,它的子进程也为用户进程;2号kthreadd进程为内核进程,其子进程也为内核进程。所以,判断是否为内核进程是看它跟2号进程的关系。此外,0号进程idle也是内核进程。init进程init进程是所有其他进程的祖先进程,是系统启动时第一个被......
  • event 10513将禁止smon进程进行事务回滚
    Oracle参数之event10513发布时间:[2012-4-10]    来源:    作者:    点击:我们设置Oracle参数event10513将禁止smon进程进行事务回滚。在进行troubleshooting时,如shutdownabort后设置该速度可以加快数据库的open速度,注意加快速度的同时,也可能带来数据库一致性问......