0
点赞
收藏
分享

微信扫一扫

Linux进程控制编程

船长_Kevin 2022-03-11 阅读 85
linux

进程控制理论基础

进程的定义:进程是一个具有一定独立功能的程序的一次运行活动,同时也是资源分配的最小单元

ps:如果当前进程没有创建线程,则当前的进程称为主线程。

程序是放到磁盘的可执行文件

进程是指程序执行的实例

进程是动态的,程序是静态的:程序是有序代码的集合;进程是程序的执行。通常进程不可在计算机之间迁移;而程序通常对应着文件、静态和可以复制。

进程是暂时的,程序是长久的:进程是一个状态变化的过程,程序可长久保存。

进程与程序组成不同:进程的组成包括程序、数据和进程控制块(即进程状态信息)

进程与程序的对应关系:通过多次执行,一个程序可对应多个进程;通过调用关系,一个进程可包括多个程序。

进程的生命周期:

创建:每个进程都是由其父进程创建进程可以创建子进程,子进程又可以创建子进程的子进程。

运行:多个进程可以同时存在进程间可以通信

撤销:进程可以被撤销,从而结束一个进程的运行

Linux中查看进程与父进程的相关信息:

ps:查看进程状态 

-eo:列出那些

pid:进程id  (标识进程的唯一数字)

ppid:父进程的id

uid:启动进程的用户id

comm:当前进程内容

cmd 当前进程执行的指令(带[ ]为系统执行指令,其余为当前用户执行指令)

指令调用:ps -eo pid,ppid,comm,cmd

查看进程树:pstree

获取进程id:pid_t getpid(void)

进程的三大状态

执行状态:进程正在占用CPU

就绪状态:进程已具备一切条件,正在等待分配CPU的处理时间片

等待状态:进程不能使用CPU,若等待事件发生则可以将其唤醒

Linux进程

Linux系统是一个多进程的系统,它的进程之间具有并行性、互不干扰等特点。也就是说,每个进程都是一个独立的运行单位,拥有各自的权利和责任。其中,各个进程都运行在独立的虚拟地址空间,因此,即使一个进程发生异常,它也不会影响到系统中的其他进程。

Linux下进程地址空间

Linux中的进程包含3个段,分别为“数据段”、“代码段”和“堆栈段”。

“数据段”存放的是全局变量、常数以及动态数据分配的数据空间;

“代码段”存放的是程序代码的数据。

“堆栈段”存放的是子程序的返回地址、子程序的参数以及程序的局部变量等。

进程互斥

进程互斥是指当有若干进程都要使用某一共享资源时,任何时刻最多允许一个进程使用,其他要使用该资源的进程必须等待,直到占用该资源者释放了该资源为止。

临界资源

操作系统中将一次只允许一个进程访问的资源称为临界资源。

临界区

进程中访问临界资源的那段程序代码称为临界区,为实现对临界资源的互斥访问,应保证诸进程互斥进入各自的临界区。

进程同步

一组并发进程按一定顺序执行的过程称为进程间的同步,具有同步关系一组并发进程称为合作进程,合作进程间互相发送的信号称为消息或事件

进程调度

概念:按一定算法,从一组待运行的进程中选出一个来占有CPU运行

调度方式:抢占式、非抢占式

调度算法

先来先服务调度算法

短进程优先调度算法

高优先级优先调度算法

时间片轮转法

死锁

多个进程因竞争资源而形成一种僵局若无外力作用,这些进程将永远不能再向前推进

僵尸进程

产生原因:

当前进程中生成一个子进程,一般需要调用fork这个系统调用,fork这个函数的特别之处在于一次调用,两次返回,一次返回到父进程中,一次返回到子进程中,我们可以通过返回值来判断其返回点。此时如果子进程先于父进程退出, 同时父进程又没有调用wait/waitpid,则该子进程将成为僵尸进程。

危害:

1、僵尸进程会占用系统资源,如果很多,则会严重影响服务器的性能;

2、孤儿进程不会占用系统资源,最终是由init进程托管,由init进程来释放;

消除方式:

(1) 让僵尸进程成为孤儿进程,由init进程回收;(手动杀死父进程)

(2) 调用fork()两次;

(3) 捕捉SIGCHLD信号,并在信号处理函数中调用wait函数;

进程控制编程

获取id

#include <sys/types.h>

#include <unistd.h>

pid_t getpid(void)     获取本进程ID。

pid_t getppid(void)    获取父进程ID

进程创建-fork

#include <unistd.h>

pid_t fork(void)  [括号内一般不添加]

功能:创建子进程(继承父进程的空间、变量,而且父进程子进程并发的,谁先谁后完全是随机的)

fork的奇妙之处在于它被调用一次,却返回两次(一次返回给父进程当前子进程id、一次返回给子进程0),它可能有三种不同的返回值。

进程创建-vfork

#include <sys/types.h>

#include <unistd.h>

pid_t vfork(void)

功能:创建子进程(不继承父进程的空间、变量,且子进程先运行,子进程内部用_exit(0),程序结束用exit(0)

ps:此种创建下,父进程在两种情况下运行

1、子进程运行结束

2、子进程执行新的任务

exec函数族

exec用被执行的程序替换调用它的程序

区别:  

1、fork创建一个新的进程,产生一个新的PID。

2、exec启动一个新程序,替换原有的进程,因此进程的PID不会改变

#include<unistd.h>

int execl(const char * path,const char * arg1, ....)

参数:

path:被执行程序名(含完整路径)。

arg1 – argn: 被执行程序所需的命令行参数,含程序名。以空指针(NULL)结束。

#include<unistd.h>

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

参数:path:被执行程序名(含完整路径);argv[]: 被执行程序所需的命令行参数数组。

#include <stdlib.h>           

int system( const char* string )

功能:调用fork产生子进程,由子进程来调用/bin/sh -c string来执行参数string所代表的命令

进程等待1

#include <sys/types.h>

#include <sys/wait.h>

pid_t wait (int * status)

功能: 阻塞该进程,直到其某个子进程退出。当父进程不想知道子进程状态时()内使用NULL。

进程等待2

#include <sys/types.h>

#include <sys/wait.h>

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

pid_t pid:指定的进程

options取0时意味着阻塞等待WNOHANG:

取“WNOHANG”意味着非阻塞等待

pid<-1:取该负数的绝对值 

pid=-1:等于当前进程的任何子进程

举报

相关推荐

0 条评论