进程
进程控制块PCB
任何进程在运行时都会有一个进程信息; 可以使用ps aux
查看部分信息。
task_struct
进程id C语言中用pid_t类型表示
进程状态:运行、停止、僵尸等
进程切换时保存和恢复的一些CPU寄存器
控制中断
当前工作目录
umask掩码
文件描述符表,包含指向很对file结构体的指针
用户id和组id
和信号相关的信息
控制终端、session
进程可以使用的资源上限Resource limit
进程控制fork
fork
根据一个现有进程复制出一个基本一模一样的新进程,可以使用pstree
查看进程图谱,
fork
#include<unistd.h> pid_d fork(void);
除了pid不同,其他的两个进程都相同,包括内存寄存器相同。
但信号量、内存锁、信号锁都不相同。
调用失败返回-1
父进程拿到的pid返回值大于0,子进程拿到的pid = 0 ;
#include<stdio.h>
#include<unistd.h>
#incldiue<stdlib.h>
int main(void){
char* msg;
int n = 0 ;
pid_t pid = fork();
if(pid < 0){
perroe("fork");
exit(1);
}
if(pid = 0){
//子进程
msg= 'child process~\n';
n = 6;
}else{
msg = "parent process\n";
n = 3;
}
while(n > 0){
printf(msg);
sleep(1);
n--;
}
return 0 ;
}
父进程结束了,子进程还在输出,运行结果看内存调度情况,情况随机
僵尸进程与孤儿进程
僵尸进程
一个进程死掉之后,父进程会释放孩子进程的资源,若一个进程已经死掉,但是其占用的资源没有被释放,则此时孩子进程变成了僵尸进程。
孤儿进程
其父进程已经死掉,则此进程被称为孤儿进程,后续的孤儿由1号进程收留。
练习
#include<sys/types.h> #incldue<unistd.h> pid_t getpid(void); pid_t getppid(void);
fork在子进程中返回0 ,子进程可以调用getpid得到自己进程id,调用getppid得到父进程的id;
而父进程可以使用getpid得到自己的id,但是其子进程的id只有在fork的时候做记录才知道。
创建10个子进程,并打印他们的id和pid
#include<stdio.h>
#include<unistd.h>
#incldiue<stdlib.h>
#include<sys/types.h>
int main(void){
char* msg;
int n = 0 ;
for(int i = 0 ; i < 10; i++){
pid_t pid = fork();
if(pid < 0){
perror("fork");
exit(1);
}
if(!pid){
//child
printf("child[%d],self=%d,parent]=%d",i,getpid(),getppid());
sleep(1);
break;//记得break,不然会导致子进程也循环创建进程
}
}
return 0 ;
}