linux进程

一、进程

1、什么是进程?

进程是程序的一次执行,进程为应用程序的运行实例,是应用程序的一次动态执行。看似高深,我们可以简单地理解为:它是操作系统当前运行的执行程序。进程是程序在计算机上的一次执行活动。当你运行一个程序,你就启动了一个进程。进程包括程序和数据两部分。进程是可以与其他程序并发执行的程序的一次执行,是系统进行资源分配和调度的一个独立单位。

2、如何查看系统中有哪些进程?
2.1、使用ps-aux指令查看

以上进程指令截取部分,那么如何在这么多的进程中找到我要找的那一个。这里需要配合使用 grep来查找进程中的某一指令。

2.2、使用top指令查看当前所有的进程,类似于window任务管理器。

linux系统下使用top指令:

window任务管理器运行界面:

无论是top指令还是window任务管理器都会实时显示CPU和内存的占有率。

3、什么是进程标识符?

系统给每个进程定义了一个唯一标识该进程的非负整数叫做pid

pid = 0;称为(swapper)交换进程,作用:进程调度。

pid= 1;称为init进程,作用:系统初始化。

4、什么是父进程、子进程?

在Linux里,除了进程0以外的所有进程都是由其他进程使用系统调用fork()函数创建的,这里调用fork()函数创建新进程的进程即为父进程,而相对应的为其创建出的进程则为子进程,因而除了进程0以外的进程都只有一个父进程,但一个进程可以有多个子进程。

程序演示如下:

一个父进程希望复制自己,使父、子进程同时执行不同的代码段。这在网络服务进程中是常见的—父进程等待客户端的服务请求。当这是请求到达时,父进程调用fork(),使子进程处理此请求。父进程则继续等待下一个服务请求到达。
一个进程要执行一个不同的程序。这对 shell 是很常见的情况。在这种情况下,子进程从fork返回后立即调用exec。

注:上述代码会一直检测用户输入,如果data=1,代表有新的客户端接入,创建一个新的子进程,并且各个子进程与父进程之间不受干扰。

5、c程序的存储空间怎么分配

                             

C语言中编译后,主要把内存和ROM分为5个区,分别为栈区、堆区、全局/静态存储区、常量存储区、代码区。
<1>栈区:由编译器自动分配释放,存放局部变量、形参、返回值。

<2>由程序员分配内存和是释放。例如调用函数:malloc()和free()。

<3>全局静态区:未初始化全局静态区(.bass)、已初始化全局静态区(.data)。

<4>常量区:例如字符串abcd。

<5>代码区:存放程序的代码。

二、创建进程

在linux中fork函数是非常重要的系统调用接口,从已经存在的进程中创建一个新的进程,新进程为子进程,原进程为父进程。

1、使用fork函数创建一个进程  pid_t fork(void);

fork函数调用成功,返回两次。返回值为0,代表当前进程是子进程;返回值为非负数,代表当前

进程为父进程。代码如下:

2、通过fork返回值判断进程是否为父进程还是子进程。

如果不直接判断pid是否大于0或者等于0,而是通过访问fork函数的返回值来判断是否进入父进程还是子进程,如上所述由fork创建的新进程被称为子进程,fork函数被调用一次,但返回两次,两次返回的唯一区别是,子进程的返回值是0,父进程的返回值是新子进程的进程id。代码如下:

3、fork与vfork的区别:
3.1、vfork直接使用父进程的存储空间,不拷贝。

fork函数如下:此时子进程和父进程会相互争夺内存资源。

3.2、vfork保证子进程先执行,当子进程调用exit退出后,父进程才执行。

三、进程退出:

1、正常退出

main函数调用return                                                                         

进程调用exit(),标准c库

进程调用_exit()或者_Exit(),属于系统调用

进程最后一个线程返回

最后一个线程调用pthread_exit       

对应头文件如下:

2、异常退出:

调用abor

当进程收到某些信号时,ctrl+c

最后一个线程对取消请求做出响应

3、父进程等待子进程退出
3.1、为什么要等待子进程退出

代码演示如下:父进程会等待子进程运行3次才开始执行。

3.2、子进程退出状态不被收集,变成僵尸进程。

3.3、孤儿进程

父进程如果不等待子进程退出,在子进程之前就结束了自己的“生命”,此时子进程叫做孤儿进程;

Linux避免系统存在过多的孤儿进程,init进程会收留孤儿进程,变成孤儿进程的父进程。init进程收留孤儿进程,代码如下:

3.4、父进程等待子进程退出,并收集子进程的退出状态
过程:收集子进程的退出状态,就需要将exit( ),里面的状态码给wait(* status) 里的*status;再由返回终止状态的宏来解析状态码,最终完成对子进程的退出状态码收集。其中status是一个整型数指针。非空,子进程退出状态放在它所指向的地址中,若为空,不关心退出状态。

3.5、wait和waitpid

wait函数简单介绍:

如果其所有子进程都还在运行,则阻塞;
如果一个子进程已终止,正等待父进程获取其终止状态,则取得该子进程的终止状态立即返回;
如果它没有任何子进程,则立即出错返回。

waitpid函数中pid参数解释如下:

pid==-1等待任一子进程。 就这方面而言, waitpid与wait等效。
pid>0等待其进程ID与pid相等的子进程。
pid==0等待其组ID等于调用进程组ID的任一子进程。
pid<-1等待其组ID等于pid绝对值的任一子进程。

waitpid的options常量:

WCONTINUED若实现支持作业控制。那么由pid指定的任一子进程在暂停后已经继续,但其状态尚未报告,则返回其状态。
WNOHANG若由pid指定的子进程并不是立即可用的,则waitpid不阻塞,此时其返回值为0。
WUNTRACED

若某实现支持作业控制,而由pid指定的任一子进程已处于暂停状态,并且其状态自暂停以来还未报告过。则返回其状态。WIFSTOPPED宏确定返回值是否对应于一个暂停子进程。

代码如下:

四。函数介绍:

1、exec族函数

我们用fork函数创建新进程后,经常会在新进程中调用exec函数去执行另外一个程序。当进程调用exec函数时,该进程被完全替换为新程序。因为调用exec函数并不创建新进程,所以前后进程的ID并没有改变

exec函数族分别是:execl, execlp, execle, execv, execvp, execvpe

1.1、exec函数

exec函数执行成功后不会返回,调用失败时,会设置errno并返回-1,然后从原程序的调用点接着往下执行。

path:可执行文件的路径名字
arg:可执行程序所带的参数,第一个参数为可执行文件名字,没有带路径且arg必须以NULL结束
file:如果参数file中包含/,则就将其视为路径名,否则就按 PATH环境变量,在它所指定的各目录中搜寻可执行文件。

如上图 :./yang为可执行路径名,yang是可执行文件名,123是参数列表,必须以NULL结尾。yang.c编译后,生成可执行文件yang在当前路径目录下,然后再编译execl.c并执行execl可执行文件。用execl 找到并执行yang。

同理如果想要执行ls -l指令查看文件权限,可以先找到ls的路径,再赋参数-l给ls,如下图:

 1.2、 execlp函数

带p的一类exac函数,包括execlp、execvp、execvpe,如果参数file中包含/,则就将其视为路径名,否则就按 PATH环境变量,在它所指定的各目录中搜寻可执行文件。所以execlp函数能通过环境变量PATH查找到可执行文件p

 1.3、 execvp函数

带v不带l的一类exac函数,包括execv、execvp、execve,应先构造一个指向各参数的指针数组,然后将该数组的地址作为这些函数的参数。
如char *arg[]这种形式,且arg最后一个元素必须是NULL,例如char *arg[] = {“ps”,“NULL”,NULL};

 1.4、 execv函数

execvp不需要加绝对路径,execv需要加绝对路径

2、system函数

返回值:如果system()在调用/bin/sh时失败则返回127,其他失败原因返回-1。若参数string为空指针(NULL),则返回非零值。

函数原型:    #include <stdlib.h>

                      int system(const char *command);

代码演示如下:

3、popen函数 

popem 函数比system函数的好处是可以获取运行结果

函数原型如下:

       #include <stdio.h>

       FILE *popen(const char *command, const char *type);

       int pclose(FILE *stream);

参数说明:

commmand:是一个指向以NULL结束的shell命令字符串的指针,这行命令将被传到bin/sh并使用-c标志,shell将执行这个命令。

mode:只能是读或者写的一种,得到的返回值(标准i/o流),也具有和type相对应的只读或者只写类型,如果type是“r”,则文件指针连接到command的标准输出;如果type是“w”,则文件指针连接到command的标准输出。

返回值:如果调用成功,则返回一个读或者打开文件的指针,如果失败,返回NULL。

代码演示如下:

  • 25
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值