Linux初识进程

(。・∀・)ノ゙嗨!你好这里是ky233的主页:这里是ky233的主页,欢迎光临~icon-default.png?t=N7T8https://blog.csdn.net/ky233?type=blog

点个关注不迷路⌯'▾'⌯

目录

一、冯诺依曼体系结构

二、操作系统

1.操作系统的概念

三、进程

1.如何让管理进程

2.task_struct中的进程属性

3.那么什么是进程呢

 

四、fork函数

1.在fork之后代码是父子进程共享的

2.那么上述代码中if和else是同时进行的吗???

3.那么fork返回值id是否同时具有两个值呢???

4.父子进程哪一个先运行呢?


一、冯诺依曼体系结构

各部分的现实产物:

输入设备:键盘 、声卡

输出设备:显示屏、网卡、喇叭

存储设备:存储器

运算器和控制器:cpu

 总的来说就是,我们的cpu并不是直接从我们的输入设备中读取数据的,因为输入设备的读取的速度一般都比较慢,这样就会拖累我们cpu的速度,而内存的速度又比较快,但是价格很贵,磁盘一个T才几百,相对于内存条来说相当于不要钱了。

所以冯诺依曼体系的思想就是,内存对输入设备中的数据进行预载,cpu从内存中读取数据,在返回给内存,这样就不会受限于“木桶效应”。这样我们的运行速度就得到了显著的提升。

二、操作系统

1.操作系统的概念

首先我们要知道一个学校是怎么来管理学生的呢?总不能是校长一个一个的看着学生们吧?绝对不是!而是班主任统计出每个学生都有对应的档案,里面放着每个学生的学习情况,身高体重,各种属性,校长只需要对班主任进行管理就可以,比如评选奖学金,只要把考试成绩优异的拿出来就可以了。

那么同样的,操作系统也是这样,OS管理着内存、驱动、进程等等,再由这些对着每个下面的进行着管理。

所以管理的本质就是先描述在组织!!

三、进程

1.如何让管理进程

当我们运行一个程序的时候,本质就是一个进程,我们的操作系统中可以有很多的进程同时存在那么我们怎么管理进程呢?

答案是先描述在组织 !!

那么如何进行描述呢?

我们的进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。

这里称之为PCB!

在Linux中我们称之为task_struct! 

这是一种描述进程属性结构体,所以我们对待进程的调用就变成了根据进程的熟悉对这个结构体,对task_struct的增删查改!

2.task_struct中的进程属性

  • 标示符: 描述本进程的唯一标示符,用来区别其他进程。
  • 状态: 任务状态,退出代码,退出信号等。
  • 优先级: 相对于其他进程的优先级。
  • 程序计数器: 程序中即将被执行的下一条指令的地址。
  • 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
  • 上下文数据: 进程执行时处理器的寄存器中的数据。
  • I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
  • 记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
  • 其他信息

3.那么什么是进程呢

进程就等于对应的代码和数据+所与之对应的task_struct结构体

四、fork函数

1.在fork之后代码是父子进程共享的

int main()
  6 {
  7     printf("hello ky\n");
  8     fork();
  9     printf("hello Linux\n");
 10     return 0;                                                                                                                                                  
 11 }

我们可以看到,在fork之前,我们是单进程一个执行流走的,但是在fork之后就变成了父子进程两个执行流分别进行执行。 

一般来说我们不会让两个进程来进行同样的操作,所以我们一般是这样用的。

int main()
  6 {
  7     pid_t id = fork();
  8     if(id < 0)
  9     {
 10         //创建子进程失败
 11         perror("fork");
 12         return 1;
 13     }
 14     else if(id==0)
 15     {
 16         //fork给子进程返回0;
 17         printf("子进程,pid:%d,ppid:%d\n",getpid(),getppid());
            sellp(1);
 18     }
 19     else
 20     {
 21         //给父进程返回子进程的pid
 22         printf("父进程,pid:%d,ppid:%d\n",getpid(),getppid());
            sellp(1)                                                                                               
 23     }
 24     return 0;                                                                                                                             
 25 }                                                                                                                                         
~
   

因为fork给父进程返回子进程的pid,给子进程返回0; 

 这里我们发现父子进程分别执行了一次对应的任务 。

2.那么上述代码中if和else是同时进行的吗???

答案是当然不是,是因为id在父进程的时候是子进程的pid,在走子进程里面是0。因为给父子进程的id值不同,所以我们可以用if和else可以执行不同的内容。

3.那么fork返回值id是否同时具有两个值呢???

答案是当然不是,众所周知,在32位下一个整数是占四个字节的,所以怎么存的下两个值呢?

对于这点我们要知道,当一个函数return之后,我们的代码已经完成了吗?当然是已经完成了!

当我们准备return之前,子进程已经被创建出来了,甚至子进程就放到了运行队列中,那么,我们又直到,fork之后的代码,子进程和父进程是共享的,但其实这里的return就已经是共享的了,这里的return会被父进程和子进程分别各自返回一次!!所以当然会有两种返回值喽!这里并不代表着会保存两次

  • return也是一种写入,这里是发生了写实拷贝

4.父子进程哪一个先运行呢?

答案是不一定!!这个是由操作系统的调度器决定的!

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值