进程控制块PCB

it2025-03-20  11

进程控制块PCB(p118)

linux内核的进程控制块是task_struct结构体pcb本质是结构体,是对进程本身信息的描述。其内部成员有很多,我们重点掌握以下部分即可: 1.进程id。系统中每个进程有唯一的id,在C语言中用pidt类型表示,其实就是一个非负整数。 2.进程的状态,有就绪、运行、挂起、停止等状态。 3.进程切换时需要保存和恢复的一些CPU寄存器。 4.描述虚拟地址空间的信息。 5.描述控制终端的信息。 6.当前工作目录(curent Working Directory)。 umask掩码。 7.文件描述符表,包含很多指向file结构体的指针。 8.和信号相关的信息。 9.用户id和组id。 10.会话(Session)和进程组。 11.进程可以使用的资源上限(Resource Limit)。进程是一个实体,包括:文本区域,数据区域,堆栈区域进程标识:进程0表示内核态进程(idle/swapper),是系统启动过程中的第一个进程,进程1表示用户态进程(init进程)fork函数:返回值有两个,一个是父进程的返回值(PID>0 子进程的id),另一个是子进程的返回值(PID=0)。两个进程同时向下执行,遇到末尾的退出语句时退出。

进程共享

父子进程fork之后的相异之处:

相同之处:1.全局变量(不能共享,各自有各自的代码段数据,它们是独立的),2. .data(不会共享,各自有各自的值),3. .text(代码段),4.栈,5.堆,6.环境变量,7.用户id,8.宿主目录(由用户决定(home)),9.进程工作目录,10.信号处理方式……

不同之处: 1.进程id, 2.fork返回值:父进程返回值>0,子进程返回值=0 3.各自的父进程id, 6.进程运行时间(父进程从起始位置开始计算,子进程从fork后开始计算) 7.闹钟(定时器,它跟着进程走,每个进程的都不一样) 8.未决信号集

父子进程间遵循:读时共享,写时复制原则

父子共享进程:1.文件描述符fp(打开文件的结构体),2.mmap建立的映射区(进程间通信详解)

创建一个子进程 #include<sys/types.h> #include<unistd.h> pid_t fork(void); 成功:在父进程中返回子进程的PID,失败返回-1 获取进程ID #include<sys/types.h> #include<unistd.h> pid_t getpid(void); 获取当前进程id pid_t getppid(void); 获取当前父进程id #include<sys/types.h> #include<unistd.h> uid_t getuid(void); 返回实际用户id uid_t geteuid(void); 返回有效用户id #include<sys/types.h> #include<unistd.h> uid_t getgid(void); 返回实际用户组id uid_t getegid(void); 返回有效用户组id 创建一个子进程并阻塞父进程 #include<sys/types.h> #include<unistd.h> pid_t vfork(void); 成功:在父进程中返回子进程的PID,在子进程中返回0, 失败返回-1 vfork不会将父进程中的数据空间复制到子进程中 子进程与父进程共享数据空间,父进程等待子进程先执行 创建一个子进程,代码如下: #include<stdio.h> #include<sys/types.h> #include<unistd.h> #include<stdlib.h> #include<string.h> int main() { char str[] = "从此开始!!!"; pid_t pid = fork(); if(pid == -1) { perror("fork error:"); exit(1); } else if(pid == 0) { strcmp(str,"child"); printf("I am child,my pid is:%d\n,father pid is:%d,str = %s\n",getpid(),getppid(),str); } else { strcmp(str,"father"); printf("I am father,my pid is:%d\n,father pid is:%d,str = %s\n",getpid(),getppid(),str); sleep(1); } printf("str = %s\n",str); return 0; }

创建多进程思路:

1.利用for循环创建进程fork();2.在循环的过程中每次需要结束子进程的循环,当pid == 0时break。而不需要结束父进程的循环。因为每次循环都会产生一个父进程和子进程,所以n次循环完成后会产生n个进程。如果每次循环不中断子进程,那么会产生2^n-1个进程。3.加入延时sleep(i);可以指定父/子进程的先后顺序。 #include<stdio.h> #include<sys/types.h> #include<unistd.h> #include<stdlib.h> #include<string.h> int main() { int i; for(i=0;i<5;i++) { pid_t pid = fork(); if(pid == -1) { perror("fork error:"); } else if(pid>0) { printf("I am [%d]parent,my pid is:%d\n",i,getpid()); sleep(1); } else if(pid == 0) { printf("delete [%d] child\n",i); break; } } if(i<5) { printf("I am being deleted [%d] child,my pid is:%d\n",i,getpid()); } else { sleep(i); printf("I am parent,my pid is:%d\n",getpid()); } return 0; }
最新回复(0)