pcb进程控制块
pcb本身是一个结构体(sched.h):
struct task_struct{
volatile long state;
void *stack;
atomic_t usage;
unsigned int flags;
unsigned int ptrace;
//进程id
//文件描述符
//进程的状态:初始态,就绪状态,运行状态,挂起状态,终止状态
//进程工作目录
//信号相关信息资源
//用户id组id
}
内存映射
用户空间映射:会映射到不同区域
内核空间映射:会映射到同一区域不同地方(没有隔离)
fork创建子线程
pid_t fork(void);
- 首先父fork之前的代码->父fork代码->父fork之后的代码->子fork的代码->子fork之后的代码
- getpid:获取当前进程的pid
- getppid:获取父进程的pid
#include<stdio.h>
#include<unistd.h>
int main(int argc,const char *argv[]){
printf("fork before\n");
pid_t pid= fork();
if(pid==-1){
printf("fork error");
}
if(pid==0){
printf("I am child processs!,pid=%d,ppid=%d\n",getpid(),getppid());
}else{
printf("I am parent,cpid = %d,pid=%d,ppid=%d\n",pid,getpid(),getppid());
}
printf("fork after\n");
return 0;
}
父进程共享
- 父子进程相同
刚fork后,data段,text段,堆,栈,全局变量,宿主程序目录,进程工作目录,信号处理方式。 - 父子进程不同
进程id,返回值,各自的父进程,进程创建的时间,闹钟,未决信号集 - 父子进程共享
map映射区,读时共享,写时复制
#include<stdio.h>
#include<unistd.h>
int main(int argc,const char *argv[]){
printf("fork before\n");
pid_t pid= fork();
int num=200;
if(pid==-1){
printf("fork error");
}
if(pid==0){
//num=300;
printf("I am child processs!,pid=%d,ppid=%d\n",getpid(),getppid());
}else{
num=400;
printf("I am parent,cpid = %d,pid=%d,ppid=%d\n",pid,getpid(),getppid());
}
printf("num = %d\n",num);
printf("fork after\n");
return 0;
}
进程回收
- 孤儿进程:父进程先于子进程结束则子进程会成为孤儿进程,子进程的父进程称为init进程(进程孤儿院)来回收进程-
- 僵尸进程:子进程结束,父进程尚未回收,改子进程变成僵尸编程
- 进程回收:回收的是残留在内核3-4G的数据(pcb控制块)
- wait功能
1、阻塞等待子线程退出
2、回收子线程残留的资源
3、获取子线程退出的状态
回收多个子线程,需要while循环
监听App被应用卸载
5.0以前是可以的
1、fork一个子线程
2、监听文件是否被删除,data/data/xx包名
3、exec函数执行某行命令(打开浏览器收集反馈)
//可以执行自己写好的程序,path是路径,arg0是可变的参数
int execle(const char *path, const char *arg0, ...
/*, (char *)0, char *const envp[] */);
//可以走系统的程序
int execlp(const char *file, const char *arg0, ... /*, (char *)0 */);
不会走原来的fork之后text字段,而是去执行exec函数族的命令或者程序