Linux进程学习笔记

进程

每个进程都有一个非负整数表示的唯一ID,叫做pid

pid=0 交换进程 进程调度

pid=1 init进程 系统初始化

getpid 获取自身的进程标识符
getppid 获取父进程的进程标识符

父进程与子进程

进程A创建了进程B

A父进程 B子进程

父子进程是相对概念

C程序的存储空间的分配

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-th1YSyos-1615252193600)(C:\Users\Hasee\AppData\Roaming\Typora\typora-user-images\image-20210304151124468.png)]

栈 函数调用返回地址 局部变量

堆 malloc

bss段 函数外 未初始化的数据

数据段 初始化过的变量

正文段 代码段

用fork函数创建一个进程

pid_t fork(void);

//fork函数调用成功,返回两次
//返回0			代表当前进程是子进程
//返回非负数		  代表当前进程是父进程
//调用失败,返回-1

----------fork() 1父-------------------

​ 1子-------------------

用vfork函数创建一个进程

vfork直接使用父进程存储空间,不拷贝

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

其余用法同 fork

----------vfork() 2父-------------------

​ 1子-------------------

新旧Linux 父子进程区别

旧Linux 全拷贝

新Linux 写时拷贝 copy on write

进程退出

正常退出
  1. Main函数调用return
  2. 进程调用exit(),标准C库 会先冲刷缓冲区
  3. 进程调用_exit()或 _Exit(),属于系统调用 直接退出

补充

  1. 进程最后一个线程返回
  2. 最后一个线程调用pthread_exit
异常退出
  1. 调用abort
  2. 当进程收到某些信号时,如ctrl+C
  3. 最后一个线程堆取消(cancellation)请求做出响应
#include <unistd.h>
void exit(int status);
void _exit(int status);
void _Exit(int status);
父进程等待子进程退出,并收集子进程的退出状态

调用wait函数(会返回一个状态码)

子进程退出状态不被收集,变成僵死进程(僵尸进程)

#include <sys/types.h>
#include <sys/wait.h>

pid_t wait(int *status);

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

int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);

正常退出WEXITSTATUS(status) 读取 exit(i)返回值i

用waitpid非阻塞等待 子进程也会变成僵尸进程

孤儿进程

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

Linux避免系统存在过多孤儿进程,init进程收留孤儿进程,变成孤儿进程的父进程

exec族函数

在调用进程内部执行一个可执行文件

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环境变量,在它所指定的各目录中搜寻可执行文件
perror()   打印错误原因

system函数

system()函数返回值 成功,返回进程状态值;sh不能执行,返回127;失败返回-1

system()是封装后的execl()

system()还会返回原始程序 继续执行代码

#include <stdlib.h>

int system(const char *command);
//()里 写原本要输的指令即可

popen函数

bisystem在应用中的好处:可以获取运行的输出结果

popen返回的是一个FILE 用fread读取

#include <stdio.h>

FILE *popen(const char *command, const char *mode);
//mode r输出  w输入
int pclose(FILE *stream);

获取运行的输出结果

popen返回的是一个FILE 用fread读取

#include <stdio.h>

FILE *popen(const char *command, const char *mode);
//mode r输出  w输入
int pclose(FILE *stream);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值