当前位置: 首页 > news >正文

菜鸟教程自学网重庆seo扣费

菜鸟教程自学网,重庆seo扣费,深圳科技网站建设,给出一个网站怎么做渗透测试引入 创建进程的方式我们已经学习了一个!在我们运行指令(或者运行我们自己写的可执行程序)的时候不就是创建了一个进程嘛?那个创建进程的方式称为指令级别的创建子进程! 那如果我们想要在代码中创建进程该怎么办呢? fork() for…

引入

创建进程的方式我们已经学习了一个!在我们运行指令(或者运行我们自己写的可执行程序)的时候不就是创建了一个进程嘛?那个创建进程的方式称为指令级别的创建子进程!
那如果我们想要在代码中创建进程该怎么办呢?

fork()

fork 函数的使用,见见猪跑

这是一个系统调用函数,我们可以使用 man 指令来查看函数的说明文档!
在这里插入图片描述
在这里插入图片描述

介绍:这个函数可以为调用这个函数的进程创建一个进程,我们把这个新创建出来的进程叫做子进程,调用这个函数的进程称为父进程!
返回值:如果成功创建子进程,子进程的 PID 将被返回给父进程,0 将被返回给子进程;如果创建子进程失败,-1 将返回给父进程,错误码将被设置!

好的,我们不管这么多,先来用一用!

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>int main()
{pid_t id = fork();if(id == 0) //子进程{while(1){printf("我是子进程, pid: %d, ppid: %d\n", getpid(), getppid());sleep(1);}}else if(id > 0) //父进程{while(1){printf("我是父进程, pid: %d\n", getpid());sleep(1);}}else // 子进程创建失败{perror("fork():");}return 0;
}

在上面的代码中,我们创建了一个子进程,让子进程循环打印自己的 pidppid,让父进程循环打印自己的 pid 我们来验证一下通过 fork 函数创建出来的进程到底是不是调用该函数进程的子进程。
在这里插入图片描述

我们看到子进程的 ppid 是 4176994,父进程的 pid 是4176994。说明我们的结论没有问题呢!

看到这里,你可能会有很多问题🤔~不着急我们一个一个来解决!

问题一:

为什么 fork 要给子进程返回 0,给父进程返回子进程的 pid

你想啊!一个进程只能调用一次 fork 函数嘛?显然不是的!我循环调用 fork 一百次,那么父进程应该如何区分这么多的子进程呢?那还不得靠返回值啦!
因此,fork 函数返回不同的值就是为了让父进程能够区分自己创建的子进程,从而让不同的执行流执行不同的代码!

问题二:

fork 函数究竟在干什么?干了什么?

我们在进程的概念部分知道了:进程 = PCB (进程控制块, Linux 环境下叫 task_struct) + 代码和数据。这也就意味着,task_struct 中必然维护着指针信息,能够通过 task_struct 找到进程的代码和数据!因为 linux 操作系统对进程的管理,本质上是对 task_struct 的管理。CPU 要执行进程的代码必须能通过 task_struct 找到进程的代码和数据!


fork 创建子进程的时候,操作系统首先为子进程创建 task_struct 结构体,并初始化结构体中的属性~但是,在初始化指向子进程代码和数据的指针的时候,应该怎么办呢?因为子进程并没有自己的代码和数据哇!那操作系统就说啦,子进程不是父进程创建的嘛,就让这个指针指向父进程的代码和数据吧!


于是,我们得出了一个重要的结论:fork 之后,父子进程的代码共享
在这里插入图片描述

父进程为什么要创建子进程,不就是想让子进程来帮忙的嘛!因此,为了让父子进程执行不同的代码,就需要通过 fork 不同的返回值来实现!

问题三:

一个变量怎么会有不同的内容?如何理解?

在任何操作系统中,进程在运行的时候具有独立性!
其实根据常识也能证明:你的电脑上同时运行着 QQ 和 微型这两个进程!突然 QQ 这个进程挂掉了!QQ 挂掉了会影响微信这个进程的运行嘛?显然是不会的!

在这里插入图片描述
在来看这张图,我们说 fork 之后,父子进程的代码和数据是共享的,我们又说进程之间是互相独立的!假设我们的子进程想要修改父进程中的数据怎么办呢?这种操作会被允许嘛?
我们先来写一个代码看看结论!

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>int g_val = 100;int main()
{pid_t id = fork();if(id == 0) //子进程{int cnt = 0;while(1){printf("我是子进程, g_val = %d\n", g_val);cnt++;if(cnt == 3){printf("change g_val\n");g_val = 200;}sleep(1);}}else if(id > 0) //父进程{while(1){printf("我是父进程, g_val: %d\n", g_val);sleep(1);}}else // 子进程创建失败{perror("fork():");}return 0;
}

在上面的代码中我们定义了一个全局变量 g_val 在父子进程中每隔一秒打印 g_val 的值。在子进程中 3 秒之后将 g_val 修改了,我们观察父子进程打印 g_val 的结果有什么变化!
在这里插入图片描述
我们看到在子进程中,g_val 变成了 200,父进程中 g_val 还是 100。这是为什么呢?我们知道进程之间是具有独立性的!因为数据可能会被修改,这就注定了父子进程之间的数据是不能共享的
那怎么办呢?在创建子进程的时候将父进程的数据拷贝一份给子进程?这样做的确没有任何问题!但是如果子进程都不对父进程的数据做修改,这不就白白给子进程拷贝了一份数据嘛!造成内存负担


于是操作系统说:当子进程要修改父进程的数据时,我再给你子进程拷贝数据吧!这个行为被称为:父子进程数据层面的写时拷贝。当操作系统检测到子进程要修改父进程的数据时,会为子进程重新分配一块内存空间!


因为代码不可能被修改,父子进程代码共享并不影响进程之间的独立性!

问题四:

一个函数是如何做到返回两次的?怎么理解?

首先,fork 是一个函数,在这个函数中负责为调用他的进程创建子进程,这个函数体的实现一定包含但不限于以下操作:

  • 创建子进程的 task_struct
  • 填充 task_struct 的内容。
  • 父子进程指向相同的代码。
  • 修改子进程的状态。等等

fork 这个函数执行到 return 语句的时候,此时子进程一定已经被创建出来了!并且父子进程指向了相同的代码!而 return 本身也是代码哇!我们的代码:pid_t id = fork()return 的本质不就是在向 id 这个变量中写入吗 (return 返回时,先把返回值写到 cpu 中的寄存器中,最后再把寄存器中的值拷贝到你接收到的变量中!)?子进程此时要修改 id 中的内容,是不是就得发生写时拷贝!因此,同一个 id 变量会有两个不同的值。

问题五:

如果父子进程被创建好,谁先运行?

答案是:不清楚,谁先运行由调度器决定!

问题六:

同一个变量名存储不同的数据,如何做到?

这个问题仙子阿没打讲解,我们等到学习进程地址空间的时候再说吧!

http://www.dinnco.com/news/62753.html

相关文章:

  • 一个用户注册的网站怎么做南安网站建设
  • 企业网站管理系统的运维服务最近大事件新闻
  • 黄石做网站的软文推广案例大全
  • 2008建立的php网站慢网络推广
  • 做石膏选图形的网站优质的seo网站排名优化软件
  • 如何做网站访百度联盟女生做sem专员的工作难吗
  • 让代理公司注册公司靠谱吗优化培训学校
  • 怎么做潮牌网站代做关键词收录排名
  • 可以自己做装修效果图的网站百度推广价格表
  • wordpress模板搜索功能404西安关键词优化平台
  • 四川眉山今天疫情实时动态防控seo排名优化网站
  • 网站 横幅程序员培训机构排名
  • wordpress建站教程mac百度推广竞价排名
  • 电子贺卡制作seo怎么优化关键词排名培训
  • 做网站赚钱还是做应用赚钱sem分析
  • 移动网站设计与制作亚马逊查关键词排名工具
  • html网站开发实例视频志鸿优化设计官网
  • 网站开发的软件有哪些上海seo公司排名
  • 30岁做网站编辑新闻热点大事件
  • 微网站建设制作设计seo排名赚app是真的吗
  • 怎么做视频在线播放网站网址解析ip地址
  • 专业建设网站服务公司金融网站推广圳seo公司
  • 那个企业建网站好站长工具使用
  • 公司建设网站的通知排名优化哪家专业
  • wix做网站广告推广费用一般多少
  • 哪些网站是用jsp做的百度人工服务热线
  • 做网站项目计划书推广普通话的意义50字
  • 做网站学什么专业女装标题优化关键词
  • 陕西企业名录大全保定网站seo
  • 襄阳商城网站建设口碑营销方案怎么写