ppt网站超链接怎么做信阳住房和城乡建设局网站
- 作者: 多梦笔记
- 时间: 2026年02月17日 18:12
当前位置: 首页 > news >正文
ppt网站超链接怎么做,信阳住房和城乡建设局网站,个人商城网站源码,安徽seo团队本文目录 一、进程创建二、GDB多进程调试 一、进程创建 在Linux中输入man 2 fork可以查看man文档中的fork的相关函数信息。 fork的作用就是创建一个子进程。 通过fork我们可以知道#xff0c;创建子进程的时候#xff0c;复制父进程的信息。 我们看看翻译的man文档信息创建子进程的时候复制父进程的信息。 我们看看翻译的man文档信息 子进程和父进程在独立的内存空间中运行。在调用 fork() 时两个内存空间的内容是相同的。其中一个进程进行的写操作、文件映射以及取消映射不会影响另一个进程。 首先我们来说说在 fork() 调用时子进程和父进程的内存空间内容是相同的这是因为 fork() 的实现机制是通过“写时复制”Copy-On-Write简称 COW来实现的。 内存空间的复制 首先fork() 的目标是创建一个与父进程几乎完全相同的子进程。为此它需要复制父进程的内存空间包括代码段、数据段、堆和栈等。在调用 fork() 的瞬间子进程的内存空间内容与父进程完全一致。当然上面两句话指的是虚拟地址空间。 在 fork() 后父子进程会有相同的虚拟地址空间映射父进程的数据和堆栈的内容在物理内存中不会立即复制。实际上操作系统使用了页表paging来标记这些内存页面为只读且标记为共享的。 写时复制Copy-On-Write机制 虽然内存空间的内容在 fork() 时是相同的但实际的物理内存并没有完全复制。操作系统采用了“写时复制”技术来优化资源使用。 在 fork() 调用后父进程和子进程共享相同的物理内存页面。只有当父进程或子进程中的任意一个对内存进行写操作时操作系统才会真正复制该页面的内容到一个新的物理页面并将修改后的页面分配给进行写操作的进程。如果父进程和子进程都没有对内存进行写操作它们将继续共享相同的物理页面。 当父进程或子进程尝试修改某一共享的内存页时操作系统才会进行实际的物理内存复制。这意味着只有在进程写入某个页面时内核才会为该页面分配新的物理内存并将原页面的内容复制到新的物理内存位置从而保证父子进程的内存内容互不影响。 所以由于 fork() 的目标是创建一个与父进程完全相同的子进程因此在调用 fork() 的瞬间子进程的内存空间内容必须与父进程一致。这是通过逻辑上的“复制”实现的虚拟地址空间而物理内存的实际复制则通过写时复制机制延迟到真正需要修改内存时才进行。 “运行在不同的内存空间”The child process and the parent process run in separate memory spaces 这句话的核心在于“内存空间”memory space的概念。内存空间指的是进程的虚拟内存空间virtual memory space而不是物理内存physical memory。每个进程都有自己的虚拟内存空间这是操作系统为进程分配的逻辑地址空间。虚拟内存空间是独立的每个进程都无法直接访问其他进程的虚拟内存空间。这种隔离是现代操作系统实现进程隔离和保护的基础。 当 fork() 创建子进程时子进程会获得一个全新的虚拟内存空间。虽然这个虚拟内存空间的内容在创建时与父进程的虚拟内存空间内容相同但它们是完全独立的。子进程无法直接访问父进程的虚拟内存空间反之亦然。 虽然父进程和子进程运行在不同的虚拟内存空间中但它们的内存内容在 fork() 调用时是相同的。一是因为逻辑上的复制在 fork() 调用时子进程的虚拟内存空间被初始化为与父进程的虚拟内存空间内容一致。这意味着子进程的代码段、数据段、堆和栈等在逻辑上与父进程相同。 二是因为写时复制Copy-On-Write操作系统通过写时复制技术优化了内存的使用。虽然虚拟内存空间的内容在逻辑上是相同的但物理内存页面并不会立即复制。只有当父进程或子进程对某个页面进行写操作时操作系统才会真正复制该页面的内容到新的物理内存中。所以只需要明确在 fork() 调用时子进程的虚拟内存空间的内容与父进程相同但这种相同是逻辑上的物理内存的复制是通过写时复制机制实现的。 在linux中新建c文件运行下面代码gcc fork.c -o fork和./fork。 /pid_t fork(void):作用创建子进程。返回值fork会返回两次一次在父进程中一次在子进程中。在父进程中返回子进程的ID在子进程中返回0.如何区分父进程和子进程就可以通过fork返回值。如果在父进程中返回-1表示创建子进程失败并且设置对应的error当系统的进程数达到了系统上限或者内存不足的时候就会失败/# includesys/types.h
includeunistd.h
includestdio.h
int main(){pid_t pid fork(); //这个pid是int类型的//因为fork会返回两个分别对应两个进程//判断是父进程还是子进程if (pid0){printf(pid: %d\n, pid);printf(我是父进程pid : %d,ppid: %d\n,getpid(),getppid());}else if(pid0){printf(我是子进程pid : %d,ppid: %d\n,getpid(),getppid());}for(int i0;i5;i){printf(i : %d, pid : %d \n,i,getpid());sleep(1);}return 0; }输出如下 当前的pid是fork程序33228ppid是32535这个是我的连接linux终端bash的进程id然后子进程id是33228能够对应上。 pid: 33228 我是父进程pid : 33227,ppid: 32535 i : 0, pid : 33227 我是子进程pid : 33228,ppid: 33227 i : 0, pid : 33228 i : 1, pid : 33227 i : 1, pid : 33228 i : 2, pid : 33227 i : 2, pid : 33228 i : 3, pid : 33227 i : 3, pid : 33228 i : 4, pid : 33228 i : 4, pid : 33227 从上面也可以看出是父进程和子进程交替在运行for循环从这一点也可以看出cpu是时间片分给父子进程交替运行。 并且父子进程都在运行for也可以看出父子进程共享了代码。 下图是父子进程虚拟地址空间示意图fork以后子进程的用户区数据和父进程一样因为是拷贝过来的内核区也会拷贝过来但是内核区的pid不一样。 父进程执行 pid_t pid fork() 得到的返回值是在栈空间得到的返回值是子进程的pid比如33228但是子进程clone得到的虚拟地址空间中的栈空间所得到的pid是0但是linux内核中子进程的pid是33228注意返回的id和自身的pid。 虚拟地址空间Virtual Address Space是现代计算机操作系统中一个非常重要的概念它是操作系统为每个进程分配的逻辑地址空间。简单来说虚拟地址空间是一个进程能够访问的内存地址范围但这些地址并不是直接映射到物理内存实际的硬件内存的地址而是通过操作系统和硬件的联合管理映射到物理内存或其他存储资源的逻辑地址。 虚拟地址空间通常由以下几部分组成 代码段Code Segment存放程序的可执行代码。 数据段Data Segment存放程序的全局变量和静态变量。 堆Heap用于动态分配内存如通过 malloc() 或 new 分配的内存。 栈Stack用于存储函数调用时的局部变量、函数参数和返回地址等。 共享库Shared Libraries存放程序运行时加载的动态链接库如 .so 文件。 未映射区域Unmapped Regions未分配给任何用途的内存区域通常用于未来扩展。 虚拟地址空间是现代操作系统实现内存管理、进程隔离和内存保护的核心机制。它使得每个进程都能在一个独立的、安全的环境中运行同时允许操作系统灵活地管理物理内存资源。 简单来说虚拟地址空间是一个进程的“私有内存世界”它通过操作系统和硬件的支持将逻辑地址与物理地址分离从而实现高效的内存管理和进程隔离。 所以总结一下就是内核此时并不复制整个进程的地址空间而是让父子进程共享同一个地址空间只要需要写入的时候才会复制地址空间从而使得各个进程拥有各自的地址空间也就是说资源的复制是在写入的时候才会进行读时共享写时拷贝。fork产生的子进程与父进程相同的文件描述符指向相同的文件夹且用户区的数据相同。 二、GDB多进程调试 使用GDB进行调试的时候 默认只能跟踪一个进程可以在fork函数调用之前通过指令设置GDB调试工具跟踪父进程或者跟踪子进程默认跟踪父进程。 set follow-fork-mode [parent(默认)|child] 命令是设置调试父进程或者子进程。 设置调试模式set detach-on-fork [on|off]默认为on表示调试当前进程的时候其他进程继续运行如果为off则调试当前进程的时候其他进程被GDB挂起。 查看调试的进程info inferiors 切换当前调试的进程inferior id使进程脱离GDB调试detech inferiors id。
includesys/types.h
includeunistd.h
includestdio.h
int main(){printf(begin\n);//判断是父进程还是子进程if (fork()0){printf(我是父进程pid : %d,ppid: %d\n,getpid(),getppid());int i;for(i0;i10;i){printf(i%d\n,i);sleep(1);}}else{printf(我是子进程pid : %d,ppid: %d\n,getpid(),getppid());int j;for(j0;j10;j){printf(i%d\n,j);sleep(1);}}return 0; }输入命令进行编译调试gcc hello.c -o hello -g然后通过gdb hello进行调试。 在12行、19行插入断点。 然后输入r、nnext、n就会发现下面的调试过程也就是gdb默认调试父进程然后子进程的代码会走掉。 在gdb环境下通过命令show follow-fork-mode可以查看现有的fork模式我们通过set follow-fork-mode child来跟踪子进程。 这个时候再继续run就会发现断点在19行停住了。 通过info inferiors可以查看调试进程并且inferior 2切换调试的进程。
- 上一篇: ppt如何做链接打开一个网站网站建设详细流
- 下一篇: ppt下载网站哪个好课件ppt模板免费下载网站
相关文章
-
ppt如何做链接打开一个网站网站建设详细流
ppt如何做链接打开一个网站网站建设详细流
- 站长
- 2026年02月17日
-
ppt模板免费下载网站有哪些河北手机网站制作企业
ppt模板免费下载网站有哪些河北手机网站制作企业
- 站长
- 2026年02月17日
-
ppt 如何做网站交互式带财运的公司名字
ppt 如何做网站交互式带财运的公司名字
- 站长
- 2026年02月17日
-
ppt下载网站哪个好课件ppt模板免费下载网站
ppt下载网站哪个好课件ppt模板免费下载网站
- 站长
- 2026年02月17日
-
ppt效果网站网站开发最严重的问题
ppt效果网站网站开发最严重的问题
- 站长
- 2026年02月17日
-
ppt中仿网站链接怎么做怎样营销
ppt中仿网站链接怎么做怎样营销
- 站长
- 2026年02月17日
