蒋豆芽的面试题专栏(13/操作系统之进程与线程)

  1. 进程有哪五种状态,如何转换?⭐⭐⭐⭐⭐

  2. 请你说说Linux的fork的作用⭐⭐⭐⭐⭐

  3. 说说写时复制⭐⭐⭐⭐⭐

  4. 说说什么是守护进程,如何创建?⭐⭐⭐⭐⭐

  5. 说说孤儿进程与僵尸进程,如何解决僵尸进程⭐⭐⭐⭐⭐

  6. 说说进程通信的方式有哪些?⭐⭐⭐⭐⭐

  7. 说说进程同步的方式?⭐⭐⭐⭐⭐

=========================================================================================================

  • 本专栏适合于C/C++已经入门的学生或人士,有一定的编程基础。
  • 本专栏适合于互联网C++软件开发、嵌入式软件求职的学生或人士。
  • 本专栏针对面试题答案进行了优化,尽量做到好记、言简意赅。这才是一份面试题总结的正确打开方式。这样才方便背诵
  • 针对于非科班同学,建议学习本人专刊文章《蒋豆芽的秋招打怪之旅》,该专刊文章对每一个知识点进行了详细解析。
  • 如专栏内容有错漏,欢迎在评论区指出或私聊我更改,一起学习,共同进步。
  • 相信大家都有着高尚的灵魂,请尊重我的知识产权,未经允许严禁各类机构和个人转载、传阅本专栏的内容。

=========================================================================================================

  1. 进程有哪五种状态,如何转换?⭐⭐⭐⭐⭐

    进程有五种状态:创建、就绪、执行、阻塞、终止

    答案解析

    创建状态
    一个应用程序从系统上启动,首先就是进入创建状态,需要获取系统资源创建进程管理块(PCB:Process Control Block)完成资源分配。

    就绪状态
    创建状态完成之后,进程已经准备好,处于就绪状态,但是还未获得处理器资源,无法运行。

    运行状态
    获取处理器资源,被系统调度,当具有时间片开始进入运行状态。如果进程的时间片用完了就进入就绪状态

    阻塞状态
    运行状态期间,如果进行了阻塞的操作,如耗时的I/O操作,此时进程暂时无法操作就进入到了阻塞状态,在这些操作完成后就进入就绪状态。等待再次获取处理器资源,被系统调度,当具有时间片就进入运行状态

    终止状态
    进程结束或者被系统终止,进入终止状态
    图片说明
    图片来源:网络(侵删)

  2. 请你说说Linux的fork的作用⭐⭐⭐⭐⭐

    fork函数用来创建一个子进程。对于父进程,fork()函数返回新创建的子进程的PID。对于子进程,fork()函数调用成功会返回0。如果创建出错,fork()函数返回-1。

    答案解析

    fork()函数,其原型如下:

    #include <unistd.h>  
    pid_t fork(void);  

    fork()函数不需要参数,返回值是一个进程标识符PID。返回值有以下三种情况:

    (1) 对于父进程,fork()函数返回新创建的子进程的PID。 (2) 对于子进程,fork()函数调用成功会返回0。

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

- 本专栏适合于C/C++已经入门的学生或人士,有一定的编程基础。 - 本专栏特点: 本专刊囊括了C语言、C++、操作系统、计算机网络、嵌入式、算法与数据结构、数据库等一系列知识点,总结出了高频面试考点(附有答案)共计309道,事半功倍,为大家春秋招助力。 - 本专栏内容分为七章:共计309道高频面试题(附有答案)

全部评论
进程IPC通信:总体来说,在内核提供了专门的结构体,对外提供一组API,对内核而言,只需要感知内核中对应的数据结构的状态就可以准确的提供服务,Linux的源码开放,学习可以通过学习内核源码以及圣经书,就可以快速入门
2 回复 分享
发布于 2021-04-25 20:32
信号和信量:信号又称为软中断,用于通知进程异步事件已经响应了。博主的文章已经提及了常见的信号,如挂起、子进程结束、ctrl+c、ctrl+z、程序的正常或者异常结束等等。(1)相关API:填充内核结构体struct sigaction,如中断服务函数地址、falg、mask(2)sigaction绑定信号,一旦信号到来,内核会自动通知进程。(3)在此基础上,支持多个信号组成信号集,因此有一族函数专门处理信号集,sigemptyset--清空信号集,必须使用,不然状态未知、sigaddset--添加信号到信号集、sigdelset--从信号集中删除信号、sigismember--测试是都加入信号集
1 回复 分享
发布于 2021-04-25 20:27
信号量(semaphore):学过计算机操作系统的话,就很清楚这和PV操作是一回事,核心是在多线程并发的环境中,保护临界资源的方法,只有得到信号量才可以进入临界区执行临界代码,否则阻塞等待,比如多人使用打印机,打印出的内容必定是一个用户完整的文档,不可能内容交叉。(1)相关API:semget创建信号量、semop实现PV操作--通过配置内核结构体struct sembuf设置初值,加1还是减1、semctl初始,删除信号量(3)更多细节。可以访问https://blog.csdn.net/weixin_39956356/article/details/86708363
1 回复 分享
发布于 2021-04-25 20:14
守护进程是fork的一个典型用例。守护进程是后台运行的特殊进程,用于执行特定的任务,一些守护进程从系统启动就会执行,直到系统关闭,一个很重要的特点是:守护进程不受终端的控制,如何实现这种效果。也就是守护进程的创建问题:(1)通过fork创建子进程,同时使用exit终止父进程,但是子进程会继承父进程会话(session),控制终端、父进程的工作目录、父进程的文件掩码、父进程的文件描述符。问题:既然守护进程不受终端的控制,使用fork又会带来这么多“耦合”?。(2)使用setsid创建一个新会话--让子进程摆脱原会话的控制、让子进程摆脱原进程组的控制和让子进程摆脱原控制终端的控制。(3)摆脱父进程工作目录chdir。(3)摆脱父进程文件掩码umask。(4)摆脱父进程文件描述符close(守护进程可能永远也不会读写从父进程继承下来的文件,不关闭占用资源)。(4)总结:后序的几个点是为了解决fork带来的问题,setsid->chdir->umask->close,也就是上面提及内容
2 回复 分享
发布于 2021-04-25 16:20
大家有发现任何疑问都可以提出来哟
2 回复 分享
发布于 2021-03-15 23:52
ve老哥说的对!作者请改下吧。写时复制知识点:VFork 是通过挂起父进程的方式,让子进程先运行,是无法写的,这样才避免了页面的复制
点赞 回复 分享
发布于 2021-04-29 20:48
共享内存:多个进程共享一段内存,效率很高,但是内核没有同步机制,用户必须定义自己的同步机制,否则会出乱子。(1)相关API:shmget创建共内存、shmat将共享内存链接进自己的地址空间、shmdt将共享内存从当前的进程分离、shmctl标记删除,当最后一个进程离开后内核会自动清理这段内存(2)思路:开辟一片内存(有一个引用计数,很像shared_ptr),需要进链接自己的空间(引用计数加1),不需要就分离开(引用计数减1),引用计数减直0,才会真正销毁这篇内存(3)更多细节。可以访问https://blog.csdn.net/weixin_39956356/article/details/86709295
点赞 回复 分享
发布于 2021-04-25 20:03
消息队列:可以理解成一个消息的链表,每一个消息就是一个记录,具有特定的优先级和访问权限,如有写权限的进程可以添加消息,有读权限的进程可以读走消息。不过注意的是,即使进程终止,消息队列也不会删除。(1)相关API:msgget创建一个消息队列,msgsnd发送,msgrcv接受,msgctl断开连接。(5)更多细节。可以访问https://blog.csdn.net/weixin_39956356/article/details/86652957
点赞 回复 分享
发布于 2021-04-25 19:55
管道pipe。(1)种类:无名和有名两种(2)区别:无名管道用于父子进程(血缘关系)--比如fork,有名管道没有血缘关系(3)特点:半双工,同一时刻只能读或者写,即总有一个进程会被阻塞。比如读进程读一个空的管道会被阻塞(4)使用:内核规定fd[0]为读端,fd[1]为写端。好比管子的两端。(5)更多细节。可以访问https://blog.csdn.net/weixin_39956356/article/details/86648643
点赞 回复 分享
发布于 2021-04-25 19:50
进程IPC通信:这些内容都出自于UNIX网络编程(卷一:套接字)、UNIX网络编程(卷二:进程通信)、UNIX环境高级编程这三本圣经,自己也总结一些内容:欢迎点击https://blog.csdn.net/weixin_39956356/category_9284185.html?spm=1001.2014.3001.5482
点赞 回复 分享
发布于 2021-04-25 18:00
僵尸进程:可以看看这文章https://www.linuxprobe.com/zombie-linux.html
点赞 回复 分享
发布于 2021-04-25 16:47
fork、vfork、写时复制:1. fork()创建子进程,拷贝父进程的数据段、代码段,以及页表项逐一复制到子进程中(注意:这才是耗时真正的原因,基于此做了很多优化) 2. 历史上引入了vfork,基本思路是把父进程挂起,让子进程先执行,这样当然就避免了页面的复制,但是也损害了并发性 3. 如何避免页面的复制呢?内核设计者引入了写时复制,就是一种惰性复制思路,尽量把高昂的操作推迟。父子进程共享页面,如果不修改,当然最好了;如果修改,内核将复制修改的页面,修改状态位COW标志不在共享,除非所有页面全部修改效率才会差到原始fork 4. 现代的内核都是加入写时复用,fork使用远多于vfork
点赞 回复 分享
发布于 2021-04-25 11:27
关于fork: fork作为进入大多数人并发中第一个“API”,代码已经不能按照传统的顺序思维理解了。目标:创建一个新进程,这个进程和父进程几乎一摸一样,之后两个进程并发执行,谁快谁慢都是未知的。使用:调用一次返回两次,一次在父进程中(>0,子进程pid),一次子进程(=0),按照返回值区别父子进程,返回0表示失败(内存不足、pid耗尽(2^16)几乎很少发生)。总结:fork好比链表:父进程-->子进程-->0。注意:通过wait/waitpid可以等待子进程结束获取其状态。最后fork的两种经典使用方法可以参考我的博客https://blog.csdn.net/weixin_39956356/article/details/86619111
点赞 回复 分享
发布于 2021-04-25 10:40

相关推荐

求offer的大角牛:不吃香菜
点赞 评论 收藏
分享
评论
4
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务