一个进程会被其他怎么把没用的进程关掉掉怎么办

新手园地& & & 硬件问题Linux系统管理Linux网络问题Linux环境编程Linux桌面系统国产LinuxBSD& & & BSD文档中心AIX& & & 新手入门& & & AIX文档中心& & & 资源下载& & & Power高级应用& & & IBM存储AS400Solaris& & & Solaris文档中心HP-UX& & & HP文档中心SCO UNIX& & & SCO文档中心互操作专区IRIXTru64 UNIXMac OS X门户网站运维集群和高可用服务器应用监控和防护虚拟化技术架构设计行业应用和管理服务器及硬件技术& & & 服务器资源下载云计算& & & 云计算文档中心& & & 云计算业界& & & 云计算资源下载存储备份& & & 存储文档中心& & & 存储业界& & & 存储资源下载& & & Symantec技术交流区安全技术网络技术& & & 网络技术文档中心C/C++& & & GUI编程& & & Functional编程内核源码& & & 内核问题移动开发& & & 移动开发技术资料ShellPerlJava& & & Java文档中心PHP& & & php文档中心Python& & & Python文档中心RubyCPU与编译器嵌入式开发驱动开发Web开发VoIP开发技术MySQL& & & MySQL文档中心SybaseOraclePostgreSQLDB2Informix数据仓库与数据挖掘NoSQL技术IT业界新闻与评论IT职业生涯& & & 猎头招聘IT图书与评论& & & CU技术图书大系& & & Linux书友会二手交易下载共享Linux文档专区IT培训与认证& & & 培训交流& & & 认证培训清茶斋投资理财运动地带快乐数码摄影& & & 摄影器材& & & 摄影比赛专区IT爱车族旅游天下站务交流版主会议室博客SNS站务交流区CU活动专区& & & Power活动专区& & & 拍卖交流区频道交流区
UID空间积分0 积分41阅读权限10帖子精华可用积分41 信誉积分100 专家积分0 在线时间1 小时注册时间最后登录
白手起家, 积分 41, 距离下一级还需 159 积分
帖子主题精华可用积分41 信誉积分100 专家积分0 在线时间1 小时注册时间最后登录
论坛徽章:0
rt,我的父进程已开始利用fork+exec启动了很多子进程,但是当我的父进程退出的时候子进程会被init收养,我想当parent退出的时候也同时让所有的child退出,我想了一下两个方法,但是觉得都不是很好,大家帮忙看看还有什么好的方法:
(1)子进程中设置alarm,并在SIGALRM的处理函数中利用getppid()是否为1来判断,但是这会浪费我的子进程的alarm定时器~~个人觉得一个进程就有一个定时器,太宝贵了,这么一个小功能不值得浪费alarm
(2)当父进程退出的时候利用singnal(0,SIGUSR1)向进程组中的所有进程广播SIGUSR1信号,在子进程中捕捉SIGUSR1后退出,但是这种情况下,父进程在我可控的情况下退出可以控制发送这个信号,但是当如果利用kill -KILL杀死的话父进程就不会广播信号,则子进程不能退出~~
请问大家还有没有别的方法~~谢谢了~~
&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp
UID空间积分0 积分41阅读权限10帖子精华可用积分41 信誉积分100 专家积分0 在线时间1 小时注册时间最后登录
白手起家, 积分 41, 距离下一级还需 159 积分
帖子主题精华可用积分41 信誉积分100 专家积分0 在线时间1 小时注册时间最后登录
论坛徽章:0
请问子进程如何知道父进程的退出~~
上面第二种方法只是想像的结果,刚试验了一下利用kill -9杀死父进程的时候还是会发送SIGUSR1的,晕了~~~哪位帮忙解释一下
父进程所有退出的地方都使用了以下函数
void my_exit()
{
& & & & kill(0,SIGUSR1);
& & & & sleep(EXIT_WAIT_TIME);
& & & & exit(FAILURE);
}复制代码
和谐大家庭户主
UID1845851空间积分0 积分5877阅读权限70帖子精华可用积分5877 信誉积分128 专家积分0 在线时间467 小时注册时间最后登录
富足长乐, 积分 5877, 距离下一级还需 2123 积分
帖子主题精华可用积分5877 信誉积分128 专家积分0 在线时间467 小时注册时间最后登录
论坛徽章:0
请问子进程如何知道父进程的退出~~
man setpgrp
有俺家属的帖子要水,没俺家属的帖子创造家属也要水!
UID153116空间积分0 积分5440阅读权限70帖子精华可用积分5440 信誉积分175 专家积分0 在线时间602 小时注册时间最后登录
富足长乐, 积分 5440, 距离下一级还需 2560 积分
帖子主题精华可用积分5440 信誉积分175 专家积分0 在线时间602 小时注册时间最后登录
论坛徽章:0
请问子进程如何知道父进程的退出~~
父进程死的时候好像会给儿子们发消息的吧
具体是哪一个忘记了呀
衡阳学开车找元师傅
[天籁妙,山水雅,醉露为酒玉为花,
若人问我归何处,彩云深处是我家。]
UID空间积分0 积分41阅读权限10帖子精华可用积分41 信誉积分100 专家积分0 在线时间1 小时注册时间最后登录
白手起家, 积分 41, 距离下一级还需 159 积分
帖子主题精华可用积分41 信誉积分100 专家积分0 在线时间1 小时注册时间最后登录
论坛徽章:0
请问子进程如何知道父进程的退出~~
我认为setpgid可以设置parent和child的组ID为同一个进程组,parent正常退出的话是可以广播一个信号的,但是问题是当parent异常退出(如被kill -9杀掉)的时候它就不会向子进程发送任何信号,这时我的子进程就成为了不可控进程~~在补充以下我的第二个帖子是错的,我刚验证过kill -9 parentPID的时候parent不会向child发送SIGUSR1~~~
UID空间积分0 积分41阅读权限10帖子精华可用积分41 信誉积分100 专家积分0 在线时间1 小时注册时间最后登录
白手起家, 积分 41, 距离下一级还需 159 积分
帖子主题精华可用积分41 信誉积分100 专家积分0 在线时间1 小时注册时间最后登录
论坛徽章:0
请问子进程如何知道父进程的退出~~
原帖由 &bleem1998& 发表:
父进程死的时候好像会给儿子们发消息的吧
具体是哪一个忘记了呀
应该不会,因为我的child中没有处理SIGTERM信号,即其为缺省处理,那么当child收到SIGTERM后会退出,但是现在的验证结果是child活得好好的~~
UID153116空间积分0 积分5440阅读权限70帖子精华可用积分5440 信誉积分175 专家积分0 在线时间602 小时注册时间最后登录
富足长乐, 积分 5440, 距离下一级还需 2560 积分
帖子主题精华可用积分5440 信誉积分175 专家积分0 在线时间602 小时注册时间最后登录
论坛徽章:0
请问子进程如何知道父进程的退出~~
那可能是我搞错了
如果想同时死掉用线程算了
想不死都不行
衡阳学开车找元师傅
[天籁妙,山水雅,醉露为酒玉为花,
若人问我归何处,彩云深处是我家。]
UID空间积分0 积分2107阅读权限30帖子精华可用积分2107 信誉积分100 专家积分0 在线时间16 小时注册时间最后登录
家境小康, 积分 2107, 距离下一级还需 -107 积分
帖子主题精华可用积分2107 信誉积分100 专家积分0 在线时间16 小时注册时间最后登录
论坛徽章:0
请问子进程如何知道父进程的退出~~
1.为什么不用线程?
2.子进程定时通过管道给父进程发条消息,来确认
越来越糊涂
UID空间积分0 积分41阅读权限10帖子精华可用积分41 信誉积分100 专家积分0 在线时间1 小时注册时间最后登录
白手起家, 积分 41, 距离下一级还需 159 积分
帖子主题精华可用积分41 信誉积分100 专家积分0 在线时间1 小时注册时间最后登录
论坛徽章:0
请问子进程如何知道父进程的退出~~
原帖由 &fwizard& 发表:
1.为什么不用线程?
2.子进程定时通过管道给父进程发条消息,来确认
1、因为以前有子模块已经按照这种思想开发了出来,不想重复工作~~:)
2、如果child不进行write管道的话也不会知道parent的退出吧~~?也就是说我的child还得定时去write这个pipe看什么时候出错,这好像还没有用alarm来检测ppid方便呢~~:)
我想了另一种方法,还没有试验,就是利用atexit注册退出函数~~看看行不行~~
UID153116空间积分0 积分5440阅读权限70帖子精华可用积分5440 信誉积分175 专家积分0 在线时间602 小时注册时间最后登录
富足长乐, 积分 5440, 距离下一级还需 2560 积分
帖子主题精华可用积分5440 信誉积分175 专家积分0 在线时间602 小时注册时间最后登录
论坛徽章:0
请问子进程如何知道父进程的退出~~
我想到了一个办法
刚才实验了一下很好用哦
步骤如下:
建立一个FIFO
儿子注册信号驱动IO
儿子打开FIFO读
父亲打开FIFO写
如果父亲死掉了儿子会收到SIGIO信号
不管是用kill -9还是父亲自己死掉都可以
呵呵!!!!
衡阳学开车找元师傅
[天籁妙,山水雅,醉露为酒玉为花,
若人问我归何处,彩云深处是我家。]
北京皓辰网域网络信息技术有限公司. 版权所有 京ICP证:060528号 北京市公安局海淀分局网监中心备案编号:
广播电视节目制作经营许可证(京) 字第1234号
中国互联网协会会员&&联系我们:
感谢所有关心和支持过ChinaUnix的朋友们
转载本站内容请注明原作者名及出处很多用户都想通过修改显卡控制面板的设置来来改善一下显卡性能,可当看到一个个专业术语,就望而却步了。今天就给大家说一下如何设置NVIDIA显卡控制面板。 驱动怎么装就不说了。 下面以我自身为例。先是系统图: 在桌面上右键,点击NVIDIA控制面板,见下图(手动关闭了3D显示,所以大部分用户还可以看到一个3D显示的选项) 由于GTX260+在这个分辨率上基本没有玩的很卡的游戏(除CRYSIS和一些RTS游戏),所以设置成了最高质量。 这里可以强制设定游戏的画面质量,全部是最高
在用上Win8系统后发现了一个问题,刚开机时在桌面点鼠标右键可以在菜单中看到Nvidia控制面板,过一会儿就消失了。这该怎么办?如何恢复呢?下面查看具体操作方法。 解决方法: 1、打开控制面板; 2、在打开的窗口右上角的“查看方式”选择大图标。然后就可以找到“NVIDIA控制面板”; 3、打开“NVIDIA控制面板”后在窗口的左上方点击“桌面”然后把“添加桌面上下文菜单”勾选上。 完成上面的操作后,在桌面的空白处点击鼠标右键就能再次看到Nvidia控制面板。另外,大家也可以试试右键管家这个软件,
昨天小编在玩游戏的时候,发现电脑的显卡有点运行不了,效果不怎么样,但是小编的电脑配置算是可以的啊,想想肯定是N卡没有设置的原因,后来经过小编的一系列设置,解决了问题,在网上浏览很多电脑平台网站,发现好多朋友都不知道怎么设置,所以今天就给大家带来NVIDIA控制面板怎么设置(图解),下面我们一起来看看具体内容吧。 1、首先,我们在桌面上点击鼠标右键,然后选择NVIDIA控制面板,如图所示: 2、对小编喜欢玩游戏的来说,显卡的设置性能肯定是要高好了,所以在性能设置方面,小编选择最高,如果不是玩游戏的
故障现象: 如何通过Nvidia控制面板调节显示对比度、亮度等参数。 解决方案: 1. 鼠标右键单击桌面空白位置,然后选择Nvidia控制面板; 2. 选择“显示”下的“调整桌面颜色设置”,然后点击使用“Nvidia设置”,即可通过显卡调整亮度、对比度、灰度等选项进行修改。 注意:该修改方法可以同样用于安装了Nvidia 310.XX版本驱动的Nvidia GeForce 显示芯片系列显卡。
你是否在电脑中的U盘中看见过这个RunClubSanDisk.exe程序?它为什么在我们的U盘里?具有什么功能呢? RunClubSanDisk.exe进程基本信息: 程序厂商:SanDisk闪迪公司 进程描述:Bootstrap Module 进程属性:不是Windows系统进程 使用网络:没有 启动情况:通常是用户主动点击启动 来历及作用 RunClubSanDisk.exe程序是由美国SanDisk公司(1988年成立的一家设计与销售闪存卡产品的美国跨国公司)为其发布的U盘产品而设计的默认
Metro 应用程序不包含一个“关闭”按钮,其实这是微软的特殊设计,当运行另外一个应用程序的时候,当前的应用程序就会被挂起,当资源不足时,系统就会自动关闭这个应用程序。 当然,我们也可以手动关闭应用程序。使用组合热键“Ctrl+Alt+Esc”调出任务管理器,在列表中选中需关闭的应用程序,并点击“结束任务”即可。如图: 或者Metro程序界面时,直接使用组合热键“Alt+F4”直接结束程序即可。
使用Win7系统时电脑卡机死机是常见现象,大多数是因为程序开多了,电脑配置跟不上引起的,这时我们需要关闭程序,当务之急是解决电脑卡机问题。有木有什么办法可以快速的一键关闭所有程序呢?答案是有的。 操作步骤: 1、右击左面空白处,新建一个快捷方式 2、新建后,在位置栏输入taskkill /F /FI "USERNAME eq admin" /FI "IMAGENAME ne explorer.exe" /FI "IMAGENAME ne dwm.exe",注意,admin要是你自
方法一、以管理员身份运行 当我们运行一些会对重要区域操作的程序时,如果遇到错误提示,不妨可以尝试一下“以管理员省份运行”。只要鼠标右击程序启动文件或者快捷方式选择“以管理员身份运行”,随后会弹出UAC提示或是要求输入管理员账户和密码,确定后即可运行程序。(要求管理员郑虎的密码不能为空) 方法二、选择以兼容模式运行程序 1、首先鼠标右击程序启动文件或者快捷方式,然后选择属性,在弹出来的属性面板中切换到“兼容性”选项卡,然后勾选“以兼容模式运行这个程序”,宁在下拉菜单中选择一个兼容模式,完成后点击确
Metro 应用程序不包含一个“关闭”按钮,其实这是微软的特殊设计,当运行另外一个应用程序的时候,当前的应用程序就会被挂起,当资源不足时,系统就会自动关闭这个应用程序。 当然,我们也可以手动关闭应用程序。使用组合热键“Ctrl+Alt+Esc”调出任务管理器,在列表中选中需关闭的应用程序,并点击“结束任务”即可。如图: 或者Metro程序界面时,直接使用组合热键“Alt+F4”直接结束程序即可。
Win8系统使用越来越广泛的今日,不少用户在安装了Win8系统之后都普遍表示对Win8系统非常的不熟悉,很经常因为自己无意中打开了太多的程序而导致了电脑卡顿,而且要彻底关闭后台程序的方法又不熟悉,所以今天小编特地总结了Win8系统如何关闭后台程序的方法,希望对大家有所帮助。 步骤一:在Win8系统的桌面,在Win8系统桌面底部的任务栏出点击鼠标右键,打开菜单后选择“任务管理器”; 步骤二:在Win8的“任务管理器”中,选择“进程”的选项卡,然后下拉到“后台进程”这一项; 步骤三:在“任务管理器”
有的时候程序开多了,电脑就会卡,反应慢,长时间死机。这时需要关闭程序,释放win7系统系统资源。一个一个的关闭难免太慢太麻烦,怎么一键关闭所有程序呢? 操作步骤 1、在桌面空白处右击选择“新建”、“快捷方式”,然后输入以下内容: Taskkill /F /FI "imagename ne explorer.exe" /FI "imagename ne dwm.exe" 图1 图2 2、为该快捷方式取个好听的名字即可。点击这个快捷方式,发现是不是所有运行的程序都关闭了?而且速度还很快哦。 图3 补
在win8.1系统中的应用程序,相信网友们对它有一定的了解啦,是不是跟win8系统中的应用程序很不一样呢!所以可能会造成的麻烦就是不知道怎么操作关闭应用程序。但是不要着急,今天小编就来告诉你怎么操作吧! Win8.1怎么关闭应用 Win8.1彻底关闭应用方法 其实Win8.1与Win8关闭应用方法上存在一些细节不同,因为Win8.1采用的是“一键后台掌”设计,正确的关闭应用方法为: 1、将打开的应用程序拖拽至屏幕下方,这个时候先别着急松手,而是需要多停留几秒,之后拖拽下载的应用图
ipad mini3怎么关闭后台程序呢?很多用户对于ipad mini3如何关闭后台程序还不是很清楚吧,下面小编为大家介绍一下ipad mini3关闭后台程序方法,还不了解的一起来看看吧。 ipadmini3关闭后台程序教程: 1)首先,跟以往一样,双击“HOME”键。 2)双击“HOME”键后,上面是应用缩略图,下面为应用ICOM。 3)如果想要关闭某个应用,可以直接按住该应用的缩略图往上拖出界面即可。 4)更个性一点话,大家也可以使用多点触控,同时关闭多个后台应用。
Win8系统是目前最新一代操作系统,也是微软公司开发的一款最具革命性变化的操作系统,主要是增加了触摸屏设备的触控体验,在操作上已经与我们熟悉的XP、Win7系统有不少改变。对于初次使用Win8系统,往往会遇到不少问题,比如不知道如何关机,不知道Win8怎么关闭程序等,对于关机相关问题,早有介绍,接下来本文与大家介绍下关闭Win8程序的几种方法。 关闭Win8关闭方法一:开始屏幕关闭Win8程序方法 如果想关闭Win8开始屏幕中打开的应用,可以将鼠标移动至屏幕顶部,当鼠标箭头变成“小手”时,点住并
1,在“开始”菜单中选择“默认程序”。 2,选择“将文件类型或协议与程序关联”。 3,以修改*.mp3为例修改方法:首先选中要修改的项目“.mp3”,上方显示当前此文件类型打开的默认程序。 4,点击右上方“更改程序”按钮。 5,在程序列表中选择适合的程序,若没有找到需要程序,可以点“浏览”进行手工确定。全部修改完毕之后点“确定”结束。
Win8系统关闭应用程序的方法: a 、如果使用是鼠标,则单击应用顶部,然后将其拖至屏幕底部。 b、如果使用触控操作,则将应用拖至屏幕底部。 c、有关如何关闭应用的视频。 (若要查看采用你的语言的字幕,请点击或单击“关闭字幕”按钮。) d、在使用完桌面应用之后(特别是在关闭电脑之前)关闭它们仍不失为好方法。
在Win8/8.1系统中,如果开启了很多应用程序的话如何快速关闭呢?下面系小编就为大家介绍一下Win8/8.1系统关闭应用程序快捷键。 1.我们可以把鼠标移动到屏幕左上角然后向下滑动即可看到所有后台挂起的应用; 2.这个时候我们可以通过鼠标右键将他们关闭或者贴靠至左右(snap view); 3.更快捷的关闭方法我们可以直接按鼠标中键~是不是很便捷呢.
当我们使用win7系统的时候,经常会遇到启动某个应用程序,系统却弹出“停止工作,联机检查解决方案并关闭该程序”的对话框,这时候我们该怎么处理这种问题,顺利启动应用程序呢?下面来看小编的操作。 1、在win7系统键盘上按下“Win+R”组合键进入“运行”菜单,在里面键入“regedit”命令后,我们直接按下回车键开启“注册表编辑器”窗口。 2、在系统弹出的“注册表编辑器”里面。按照顺序一一点开“HKEY_LOCAL_MACHINE/SOFTWARE/Classes/CLSID/{20D04FE0-
如果IE遇到上述的错误时,大部分的问题都是由于加载项所引起的,因为IE升级到了最新的IE11,有一些加载项可以会存在与IE不兼容的情况,因此为了解决这个问题必须要切换到Internet Explorer的无加载项模式。 首先按下快捷键 WIN+R 打开执行,输入下列命令: "C:Program FilesInternet Exploreriexplore.exe" -extoff 执行以后会显示如下图的窗口,并且在底下会出现管理加载项的通知: 建议先把所有的加载项关闭,然后逐一开启会使用到的加载
该网友更新Win10系统预览版后,Nvidia显卡控制面板打不开,有时候能打开有时候无反应。而且重装就能打开,重启下就又打不开了。 根据网友提供的解决方法,出现这问题时,应该打开任务管理器,把写着user带显卡驱动图标的进程结束一下就可以了。但这个进程无法永久关闭,关闭它会自动出现一个新的。也不知是何用途,是Win10的Bug也说不定。您所在的位置: &
Linux进程管理知识整理
Linux进程管理知识整理
Linux进程有哪些状态?什么是进程的可中断等待状态?进程退出后为什么要等待调度器删除其task_struct结构?进程的退出状态有哪些?本文中将对Linux进程管理的知识进行整理。
1、进程有哪些状态?什么是进程的可中断等待状态?进程退出后为什么要等待调度器删除其task_struct结构?进程的退出状态有哪些?
TASK_RUNNING(可运行状态)
TASK_INTERRUPTIBLE(可中断等待状态)
TASK_UNINTERRUPTIBLE(不可中断等待状态)
TASK_STOPPED(进程被其它进程设置为暂停状态)
TASK_TRACED(进程被调试器设置为暂停状态)
TASK_DEAD(退出状态)
进程由于所需资源得不到满足,从而进入等待队列,但是该状态能够被信号中断。比如当一个正在运行的进程因进行磁盘I/O操作而进入可中断等待状态时,在I/O操作完成之前,用户可以向该进程发送SIGKILL,从而使该进程提前结束等待状态,进入可运行态,以便响应SIGKILL,执行进程退出代码,从而结束该进程。
当进程退出时(例如调用exit或者从main函数返回),需要向父进程发送信号,父进程进行信号处理时,需要获取子进程的信息,因此这时不能删除子进程的task_struct。另外每个进程都有一个内核态的堆栈,当进程调用exit()时,在切换到另外一个进程前,总是要使用内核态堆栈,因此当进程调用exit()时,完成必要的处理后,就把state设置为TASK_DEAD,并切换到其他进程。当顺利地切换到其他进程后,由于该进程的状态设置为TASK_DEAD,因此这个进程不会被调度,之后当调度器检查到状态为TASK_DEAD的进程时,就会删除这个进程的task_struct结构,这样这个进程就彻底的消失了。
EXIT_ZOMBIE(僵死进程):父进程等待子进程结束时发送的SIGCHLD信号(默认情况下,创建进程都会设置在进程退出的时候向父进程发送信号的标志,除非创建的是轻权进程),此时子进程已退出,并且SIGCHLD信号已经发送,但是父进程还没有被调度运行;EXIT_DEAD(僵死撤销状态):父进程对子进程的退出信号&没兴趣&,或者在子进程退出时,父进程通过waitpid()调用等待子进程的SIGCHLD信号。
2、僵尸进程
1) 怎么产生僵尸进程
一个进程在调用exit命令结束自己的时候,其实它并没有真正的被销毁,只是进程不能被调度并处于EXIT_ZOMBIE状态,它占用的所有内存就是内核栈、thread_info结构和task_struct结构。此时进程存在的唯一目的就是向它的父进程提供信息,如果它的父进程没有调用wait或waitpid等待子进程结束,又没有显示地忽略该信号,那么它就一直保持EXIT_ZOMBIE状态。
2) 怎么查看僵尸进程
利用命令ps,看到有标记为Z的进程就是僵尸进程。
3) 怎么清理僵尸进程
父进程可以调用waitpid、wait函数来等待子进程结束
把父进程杀掉,父进程死后,僵尸进程成为&孤儿进程&,过继给init进程,init进程始终负责清理僵尸进程,它产生的所有僵尸进程也跟着消失。
3、PID管理
在Linux系统中用pid结构体来标识一个进程,通过pidmap位图来管理所有的进程号(即pid:与前面的pid结构体不是同一个意思),目的就是要更快的找到目标进程。用pid结构体来表示进程的优点:比直接用数字pid_t更容易管理(进程退出时pid回收再分配效率高),比直接用task_struct标识进程占用空间小。
pid结构体如下所示:
struct&pid&{&atomic_t&&int&&&&&&&&&&&&&&&&&&&&&&&&&&&/*存放pid数值*/&struct&hlist_node&pid_&&&&&&&&/*把该pid链到哈希表中*/&struct&hlist_head&tasks[PIDTYPE_MAX];&struct&rcu_head&&};&
因为对于32位系统来说,默认最大的pid为32768,由于pidmap位图中每一位表示这个pid是否可用,共需要32768位,正好一个物理页的大小(4*1024*8)。
pidmap结构体如下所示:
struct&pidmap&{&&&&&&&&/*&&&&&&&&&*这个变量用来统计这个结构体对应的一页物理内存中有多少个位&&&&&&&&&&&&&*是0的,即空闲pid的数量&&&&&&&&&*/&&&&&&&&atomic_t&nr_&&&&&&&&&void&*&&&&&&/*这个就是指向存放这个位图的内存页的指针*/&};&
下面首先来看Linux内核启动之初在start_kernel函数中对pidmap位图的初始化函数pidmap_init如下所示:
void&__init&pidmap_init(void)&{&&&&/*申请一页物理内存,并初始化为0*/&init_pid_ns.pidmap[0].page&=&kzalloc(PAGE_SIZE,&GFP_KERNEL);&&&/*将第0位设置为1,表示当前进程使用pid为0,即现在就是0号进程*/&set_bit(0,&init_pid_ns.pidmap[0].page);&&&&/*同时更新nr_free统计空闲pid的值*/&atomic_dec(&init_pid_ns.pidmap[0].nr_free);&pid_cachep&=&KMEM_CACHE(pid,&SLAB_PANIC);&}&
再来看Linux内核启动之初在start_kernel函数中对pid hash表的初始化函数pidhash_init如下所示:
void&__init&pidhash_init(void)&{&int&i,&pidhash_&&&&/*&&&&&*nr_kernel_pages表示内核内存总页数,就是系统DMA和NORMAL内&&&&&&&&&*存页区的实际物理内存总页数&&&&&*megabytes:统计的是内核内存有多少MB&&&&&*/&unsigned&long&megabytes&=&nr_kernel_pages&&(20&-&PAGE_SHIFT);&&&/*从下面两行代码可以看出pidhash_shift是在4~12之间的*/&pidhash_shift&=&max(4,&fls(megabytes&*&4));&pidhash_shift&=&min(12,&pidhash_shift);&pidhash_size&=&1&&;&printk(&PID&hash&table&entries:&%d&(order:&%d,&%Zd&bytes)\n&,&pidhash_size,&pidhash_shift,&pidhash_size&*&sizeof(struct&hlist_head));&&&&/*&&&&*由alloc_bootmem可知pid_hash是在低端物理内存申请的,由于&&&&&&&&*pidhash_init函数是在mem_init函数执行之前被调用的,所以这里申请&&&&&&&&&*的内存是不会被回收的&&&&*/&pid_hash&=&alloc_bootmem(pidhash_size&*&sizeof(*(pid_hash)));&if&(!pid_hash)&panic(&Could&not&alloc&pidhash!\n&);&for&(i&=&0;&i&&;&i++)&&&&&&&&/*初始化每个表的每个表项的链表*/&INIT_HLIST_HEAD(&pid_hash[i]);&}&
总结:内核维护两个数据结构来维护进程号pid,一个是哈希表pid_hash,还有一个位图pidmap。在do_fork()中每调用一次alloc_pid(),首先会通过调用alloc_pidmap()修改相应的位图,该函数的主要思想是:last记录上次分配的pid,此次分配的pid为last+1,如果pid超出最大值,那么就循环回到最初值(RESERVED_PIDS),然后测试pidmap上该pid所对应的bit是否为0,直到找到为止。其次通过hlist_add_head_rcu函数在pid_hash表中增加一项。
4、进程的堆栈
一个进程有两个堆栈:用户态堆栈和内核态堆栈。用户态堆栈的空间指向用户地址空间,内核态堆栈的空间指向内核地址空间。
当进程由于中断或系统调用从用户态(进程在执行用户自己的代码)转换到内核态(进程在执行内核代码)时,进程所使用的栈也要从用户栈切换到内核栈。
用户栈向内核栈的切换:进入内核态后,首先把用户态的堆栈地址保存在内核堆栈中,然后设置堆栈指针寄存器的地址为内核栈地址。
内核栈向用户栈的切换:把保存在内核栈中的用户栈地址恢复到堆栈指针寄存器即可。
5、Linux下进程与线程的区别
1)进程是资源分配的基本单位,线程是CPU调度的基本单位
2)进程有独立的地址空间,线程有自己的堆栈和局部变量,但是没有独立的地址空间(同一个进程内的线程共享进程的地址空间)
6、写时拷贝机制(copy on write)
为了节约物理内存,在调用fork()生成新进程时,新进程与原进程会共享同一物理内存区(调用clone()建立线程,还会共享虚拟地址空间),只有当其中一进程进行写操作时,系统才会为其另外分配物理内存页面,这就是写时拷贝机制。
详细解释如下:当进程A使用系统调用fork()创建一个子进程B时,由于子进程B实际上是父进程A的一个拷贝,因此会拥有与父进程相同的物理页面。为了节约内存和加快创建速度的目标,fork()函数会让子进程B以只读方式共享父进程A的物理页面,同时将父进程A对这些物理页面的访问权限也设为只读,这样,当父进程A或子进程B任何一方对这些已共享的物理页面执行写操作时,都会产生页面出错异常中断,此时CPU会执行系统提供的异常处理函数do_wp_page()来解决这个异常,do_wp_page()会对这块导致写入异常中断的物理页面取消共享操作,为写进程复制一份新的物理页面。最后,从异常处理函数返回时,CPU就会重新执行刚才导致异常的写入操作指令,使进程继续执行下去。
7、0号进程的建立
内核启动时&手工&建立了0号进程,即swapper进程,这是一个内核态进程,它的页表swapper_pg_dir和内核态堆栈是在内核启动建立的,这个进程定义如下:
struct&task_struct&init_task&=&INIT_TASK(init_task);&
init_task的各种进程资源对象都是通过INIT_xxx进程初始化的,在start_kernel()的最后由rest_init()函数调用kernel_thread()函数,以swapper进程为&模板&建立了kernel_init内核进程,之后这个进程会建立init进程,执行/sbin//-init文件,从而把启动过程传递到用户态。而swapper进程则执行cpu_idle()函数让出CPU,以后如果没有任何就绪的进程可调度执行,就会调度swapper进程,执行cpu_idle()函数,这个函数将调用tick_nohz_stop_sched_tick()进入tickless状态。
8、进程的切换
1) 主动切换
当前进程主动进行可能引起阻塞的I/O操作,此时当前进程被设置为等待状态,加入到相关资源的等待队列,并调用schedule()函数让出CPU。
进程主动通过exit系统调用退出。
2) 被动切换
时间片到期
I/O中断唤醒了某个I/O等待队列中的更高优先级的进程
由于这两种情况通常发生在时钟中断或者其他I/O中断处理函数中,而中断上下文环境下不能阻塞进程,所以通常中断处理程序中通过设置need_resched标志请求调度,这个调度被延迟到中断返回处理。
9、Linux系统的进程间通信的方式
管道(pipe):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用(进程的亲缘关系通常是指父子进程关系)。
命名管道(named pipe):命名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
信号量(semophore):信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
消息队列(message queue):消息队列就是一个消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
信号(sinal):信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
共享内存(shared memory):共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的IPC方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号配合使用,来实现进程间的同步和通信。
套接字(socket):套接字也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同主机间的进程通信。
10、Linux进程调度机制
1) 什么是调度
从就绪的进程中选出最适合的一个来执行
2) 学习调度需要掌握哪些知识点
3) 调度策略
SCHED_NORMAL:普通的进程
SCHED_FIFO:先入先出的实时进程
SCHED_RR:时间片轮转的实时进程
4) 调度器类
分为CFS调度类和实时调度类。
CFS调度类是针对普通进程的,采用的方法是完全摒弃时间片而是分配给进程一个处理器使用比重。
实时调度类分为SCHED_FIFO和SCHED_RR。
SCHED_FIFO实现了一种简单的、先入先出的调度算法:它不使用时间片,可以一直执行下去,只有更高优先级的SCHED_FIFO或者SCHED_RR任务才能抢占SCHED_FIFO任务。如果有两个或者更多的同优先级的SCHED_FIFO进程,它们会轮流执行,但是依然只有在它们愿意让出处理器时才会退出。
SCHED_RR与SCHED_FIFO大体相同,只是SCHED_RR级的进程在耗尽事先分配给它的时间后就不能再继续执行了。
5) 调度时机
& 在内核中直接调用schedule():当进程需要等待资源而暂时停止运行时,会把进程的状态
& 设置为等待状态,并主动请求调度,让出CPU。
& 例:current-&state=TASK_INTERRUPTIBLE;
& & & & &schedule();
用户抢占:内核即将返回用户空间的时候,如果need_resched标志被设置,会导致schedule()被调用,此时就会发生用户抢占。
内核抢占:只要重新调度是安全的,那么内核就可以在任何时间抢占正在执行的任务。
6) 调度步骤
清理当前运行中的进程
选择下一个要运行的进程
设置新进程的运行环境
进程上下文切换
Linux进程管理之问题
1、为什么调用fork()函数将返回两次?
这是因为在do_fork-&copy_process-&copy_thread函数中,将子进程的用户态堆栈的开始地址设置为父进程的用户态堆栈的开始地址,这样当父子进程从内核态返回到用户态的时候,返回的地址相同,这就解释了为什么fork一次却返回两次的原因。
2、为什么要在task_struct中设置mm和active_mm两个mm_struct成员呢?
这是由于内核线程没有用户态地址空间,所以它的mm设置为NULL,但是由于页目录的地址是保存在mm结构中的,从其他进程切换到这个内核态线程时,调度器可能需要切换页表,为此增加了一个active_mm,对于mm为NULL的内核态线程,就借用其他进程的mm_struct,也就是说把它的active_mm指向其他进程的mm结构,当进行进程切换时,统一使用active_mm就可以了。但是其他进程不是有自己独立的页表吗?由于内核态线程只使用内核地址空间,因此这不会有问题。
3、有如下说法:1.task_struct的mm成员用来描述3GB用户态虚拟地址空间;2.内核线程可以借用上一个调用的用户进程的mm中的页表来访问内核地址空间。如果是这样的话,那么task_struct的mm成员能不能描述1GB的内核地址空间?如果不能的话,为什么会有2这种说法?
task_struct的mm成员不能描述1GB的内核地址空间,只是因为mm成员中保存了页目录的信息pgd_t,而且所有进程共享1G的内核态地址空间,所以可以使用上一个用户进程的mm中的页表访问内核地址空间。
4、为什么所有进程共享1G的内核态地址空间?
因为fork()会复制当前进程的task_struct结构,同时会为新进程复制mm结构。此时当前进程的3GB~4GB的内核态虚拟地址对应的页表项(页目录项)被复制到进程的页表项(页目录项)中,所以说所有进程共享1G内核态地址空间。但是对于用户态虚拟地址区域,则把它的进程页表项(页目录项)设置为只读,这样当其中一个进程对其进行写入操作时,do_page_fault()会分配新的物理页面,并建立映射,从而实现COW机制。
5、父进程要求子进程退出时发送信号,那么父进程要求子线程退出时发送信号吗?为什么?
父进程不要求子线程退出时发送信号,这是因为子线程共享父进程的一些资源,所以不需要父进程来获取这些信息,也就不需要向父进程发送信号。这一点可以在do_fork-&copy_process
& & & & & & & & p-&exit_signal=(clone_flags & CLONE_THREAD) ? -1 :(clone_flags &CSIGNAL);
以及do_exit-&exit_notify
& & & & & & & & if (tsk-&exit_signal != -1 && thread_group_empty(tsk)) {
& & & & & & & & int signal = tsk-&parent == tsk-&real_parent ? tsk-&exit_signal : SIGCHLD;
& & & & & & do_notify_parent(tsk, signal);
& & & & & &} else if (tsk-&ptrace) {
& & & & & & &do_notify_parent(tsk, SIGCHLD);&
& & & & & &}
中看出来。
6、 为什么子进程退出时,如果父进程没有调用wait等待子进程结束,则子进程会变成僵尸进程?
分析如下:在内核源码中有如下的代码:
& & & & & & & & do_exit-&exit_notify-&
& & & & & & & & & & & & & &state = EXIT_ZOMBIE
& & & & & & & & & & & &if (tsk-&exit_signal == -1 &&
& & & & & & & & & & & & & & (likely(tsk-&ptrace == 0) ||
& & & & & & & & & & & & & & unlikely(tsk-&parent-&signal-&flags & SIGNAL_GROUP_EXIT)))
& & & & & & & & & & & & &state = EXIT_DEAD;
& & & & & & & & & & & &tsk-&exit_state =
说明如果定义了子进程退出时向父进程发送信号,则设置进程状态为EXIT_ZOMBIE,否则为EXIT_DEAD。而子进程退出时一定会向父进程发送
信号,所以进程的状态为EXIT_ZOMBIE,如果此时父进程调用wait等待子进程结束的话,由do_wait-&wait_task_zombie函数可以将进程的状态设置为EXIT_DEAD,并且释放进程的内核堆栈资源,最后由put_task_struct将其task_struct结构体释放掉。否则子进程会变成僵尸进程。&
【编辑推荐】
【责任编辑: TEL:(010)】
关于&&的更多文章
日晚7点整,微软公司如约发布了Windows 8.1正式版的
本期重点推荐:转角遇到Zabbix:企业级分布式系统监控部署
本专题总结了Apache软件基金会(简称ASF)中的十个命
日,Velocity China 2013 Web 性能与运维
Velocity China 2013 Web 性能与运维大会上,来自各种
本书描述了Solaris 10和OpenSolaris内核中所有主要子系统的算法和数据结构,对第1版进行了大幅修订,加入了很多新的内容。全书从
51CTO旗下网站

我要回帖

更多关于 linux 关掉进程 的文章

 

随机推荐