进程的学习

exec族函数详细说明与应用:[link](https://blog.csdn.net/u014530704/article/details/73848573?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163697957116780357217266%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=163697957116780357217266&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2blogfirst_rank_v2~rank_v29-1-73848573.pc_v2_rank_blog_default&utm_term=exec&spm=1018.2226.3001.4450)。

linux系统中的程序与进程学习
程序是个静态的概念,进程是个动态的概念。只有程序运行的时候,则说明系统多了一个进程
进程标志符:每个进程都有一个非负整数,用来表示唯一的ID,叫做pid。
父进程与子进程
如果A进程创建了B进程,那么A为父进程,B为子进程,父子进程是相对的概念。
C程序的存储空间分配
正文段:代码段,
初始化的变量:数据段,
未初始的变量:bss段
堆:malloc函数相关申请空间的函数返回值存放的地址
栈:函数调用后返回的地址

fork函数创建进程:
pid fork(void);

fork函数调用成功,返回2次
返回值为0时,代表当前进程为子进程;
返回值为非负数时,代表当前进程为父进程(父进程返回值是新子进程的ID);
调用失败返回-1。

fork创建一个子进程的目的:
1、1个父进程希望复制自己,使父、子进程同时执行不同的代码段
2、1个进程要执行一个不同的程序

vfork函数也可以 创建进程
vfork函数与fork函数的区别:
1、vfork直接使用父进程存储空间,不拷贝
2、vfork保证子进程先运行,当子进程调用退出后,父进程才进行

进程退出
正常退出:
1、main函数调佣return
2、进程调用exit(),标准C库(推荐使用)
3、进程调用_exit()或者_Exit(),属于系统调用
补充:
1、进程最后一个线程返回
2、最后一个线程调用pthread_exit

异常退出:
1、调用abort
2、当进程收到某些信号时,如Ctrl+C
3、最后一个线程对取消请求做出响应

父进程等待子进程退出并需要收集子进程退出状态,如果没有收集子进程退出状态,会变成僵死进程。

等待子进程结束:
wait函函数
pid_t wait(int *status);
status:整型数指针
非空:子进程退出状态存放在它所指向的地址中。
空:不关心退出状态

如果其左右子进程都还在运行,则阻塞。
如果一个子进程已经终止,正等待父进程获取其终止状态,则取得子进程的终止状态后立即放回。
如果没有任何子进程,则立即出错返回。
如果是正常退出通过调用WEXITSTATUS(&status)来检测exit退出函数回调的子进程终止状态。

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

pid == -1:等待任一子进程。此时与wait函数等效。
pid>0 :等待其进程ID 与pid相等的子进程。
pid == 0 :等待其组ID等于调用进程组ID的任一子进程。
pid < -1 :等待其组ID等于pid绝对值的任一进程。
options:
WCONTINUED:
WNOHANG:若由pid指定的子进程并不是立即可用的,则waitpid不阻塞,此时返回值为0。
WUNTRACED:

孤儿进程:父进程如果不等待子进程退出,在子进程之前就结束自己的生命,此时子进程就叫孤儿进程。
Linux避免系统存在过多孤儿进程,init进程收留孤儿进程,变成孤儿进程的父进程。

exec族函数
功能:在调用进程内部执行一个可执行文件。可执行文件既可以是二进制文件,也可以是任何Linux下可执行的脚本文件。
函数族:exec函数族分别是:execl, execlp, execle, execv, execvp, execvpe
返回值:exec函数族的函数执行成功后不会返回,调用失败时,会设置errno并返回-1,然后从原程序的调用点接着往下执行。

函数原型:

#include <unistd.h>
extern char **environ;

int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg,..., 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[]);

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

exec族函数参数极难记忆和分辨,函数名中的字符会给我们一些帮助:
l : 使用参数列表
p:使用文件名,并从PATH环境进行寻找可执行文件
v:应先构造一个指向各参数的指针数组,然后将该数组的地址作为这些函数的参数。
e:多了envp[]数组,使用新的环境变量代替调用进程的环境变量

拓展:
export PATH=$PATH:加进程路径 可以添加进程的环境变量。

system函数

#include <stdlib.h>

int system(const char *command);

system函数成功,返回进程状态值,当sh不能执行时,返回127;失败返回-1。
system函数相当于是对exec族函数的封装

popen函数对比system函数可以获取运行的输出结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值