关于后台运行和守护android 进程守护的区别

新手园地& & & 硬件问题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活动专区& & & 拍卖交流区频道交流区
稍有积蓄, 积分 239, 距离下一级还需 261 积分
论坛徽章:0
在什么情况下必须用守护进程,或者说在那种情况下用守护进程比一般进程好,好在什么地方,谢谢各位大虾
&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp
论坛徽章:0
lz给解释下,守护进程和一般进程的区别好吗?
稍有积蓄, 积分 395, 距离下一级还需 105 积分
论坛徽章:0
:wink: 一个要守护 一个不要守护 的进程
白手起家, 积分 66, 距离下一级还需 134 积分
论坛徽章:0
守护是在后台运行的啊
一般进程运行时是要终端的啊
论坛徽章:92
原帖由 icw_zy 于
14:51 发表
在什么情况下必须用守护进程,或者说在那种情况下用守护进程比一般进程好,好在什么地方,谢谢各位大虾
参见 APUE2 相关章节.
白手起家, 积分 101, 距离下一级还需 99 积分
论坛徽章:0
我认为守护进程是一个运行于后台的进程,如果当某个进程(这个进程是个长期运行的进程)异常终止的时候,守护进程可以对该进程做相应的处理.
论坛徽章:0
原帖由 liaoweijun 于
16:46 发表
我认为守护进程是一个运行于后台的进程,如果当某个进程(这个进程是个长期运行的进程)异常终止的时候,守护进程可以对该进程做相应的处理.
这是init进程吧
家境小康, 积分 1336, 距离下一级还需 664 积分
论坛徽章:0
SSHD,HTTPD,CROND等等这都是守护进程.都是些一直要在后台跑的服务,不能被随便干扰,也不干扰其他程序.
守护进程的编写,配置,开关都是有一些惯例的.比如接收HUP信号.
北京皓辰网域网络信息技术有限公司. 版权所有 京ICP证:060528号 北京市公安局海淀分局网监中心备案编号:
广播电视节目制作经营许可证(京) 字第1234号
中国互联网协会会员&&联系我们:
感谢所有关心和支持过ChinaUnix的朋友们
转载本站内容请注明原作者名及出处linux守护进程原理及创建详解
在linux或者unix操作系统中在系统的引导的时候会开启很多服务,这些服务就叫做守护进程。为了增加灵活性,root可以选择系统开启的模式,这些模式叫做运行级别,每一种运行级别以一定的方式配置系统。 守护进程是脱离于终端并且在后台运行的进程。守护进程脱离于终端是为了避免进程在执行过程中的信息在任何终端上显示并且进程也不会被任何终端所产生的终端信息所打断。  守护进程,也就是通常说的Daemon进程,是Linux中的后台服务进程。它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。守护进程常常在系统引导装入时启动,在系统关闭时终止。Linux系统有很多守护进程,大多数服务都是通过守护进程实现的,同时,守护进程还能完成许多系统任务,例如,作业规划进程crond、打印进程lqd等(这里的结尾字母d就是Daemon的意思)。  由于在Linux中,每一个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程都会依附于这个终端,这个终端就称为这些进程的控制终端,当控制终端被关闭时,相应的进程都会自动关闭。但是守护进程却能够突破这种限制,它从被执行开始运转,直到整个系统关闭时才退出。如果想让某个进程不因为用户或终端或其他地变化而受到影响,那么就必须把这个进程变成一个守护进程。&& 根据守护进程的启动和管理方式,可以分为独立启动守护进程和超级守护进程两类&& 独立启动(stand_alone):该类进程启动后就常驻内存,所以会一直占用系统资源。其最大的优点就是它会一直启动,当外界有要求时相应速度较快,像httpd等进程;&& 超级守护进程:系统启动时由一个统一的守护进程xinet来负责管理一些进程,当相应请求到来时需要通过xinet的转接才可以唤醒被xinet管理的进程。这种进程的优点时最初只有xinet这一守护进程占有系统资源,其他的内部服务并不一直占有系统资源,只有数据包到来时才会被xinet管理员来唤醒。并且我们还可以通过xinet来对它所管理的进程设置一些访问权限,相当于多了一层管理机制。如果用两个比喻来形容两类守护进程的话一般会用银行的业务处理窗口来类比:&& 独立启动:银行里有一种单服务的窗口,像取钱,存钱等窗口,这些窗口边上始终会坐着一个人,如果有人来取钱或存钱,可以直接到相应的窗口去办理,这个处理单一服务的始终存在的人就是独立启动的守护进程;&& 超级守护进程:银行里还有一种窗口,提供综合服务,像汇款,转账,提款等业务;这种窗口附近也始终坐着一个人(xinet),她可能不提供具体的服务,提供具体服务的人在里面闲着聊天啊,喝茶啊,但是当有人来汇款时他会大声喊一句,小王,有人汇款啦,然后里面管汇款的小王会立马跑过来帮忙办完汇款业务。其他的人继续聊天,喝茶。这些负责具体业务的人我们就称之为超级守护进程。当然可能汇款人会有一些规则,可能不能往北京汇款,他就会提早告诉xinet,所以如果有人来汇款想汇往北京的话,管理员就直接告诉他这个我们这里办不到的,于是就根本不会去喊汇款员了,相当于提供了一层管理机制。针对这种窗口还存在多线程和单线程的区别:多线程:将所有用户的要求都提上来,里面的人都别闲着了,都一起干活吧;单线程:大家都排好队了,一个一个来,里面的人同一时间只有一个人在工作。这里需要注意的是超级守护进程的管理员xinet也是一个守护进程,只不过它的任务就是传话,其实这也是一个很具体很艰巨的任务哦。当然每个守护进程都会监听一个端口(银行窗口),一些常用守护进程的监听端口是固定的,像httpd监听80端口, sshd监听22端口等;我们可以将其理解为责任制,时候等待,有求必应。具体的端口信息可以通过cat /etc/services来查看。&& 服务进程后面通常会加一个d来表示,想负责http服务的httpd进程,cron服务的crond进程,这只不过是一种约定,就想银行里的工作人员需要穿特定的制服是一样的。&&&&& 每个守护进程都会有一个脚本,可以理解成工作内容说明书,还是需要分开来讲解: 独立启动守护进程:放在/etc/init.d/目录下,当然也包括xinet的shell脚本; 超级守护进程:按照xinet中脚本的指示,它所管理的守护进程位于/et/xinetd.d/下, 独立启动的守护进程启动方式很简单:& # /etc/init.d/syslog start&&& stop&&&&&& restart # service syslog start&&& 其中service命令也只能启动位于/etc/init.d/目录先的进程,这由service命令的内容来决定的;里面一定有case判断,可以查看/bin/service查看其运行方式;& 超级守护进程:xinet要启动起来,并且相应服务的人员都在,及在/etc/xinet.d/ftp里开启了此服务。超级守护进程的管理规则首先通过/etc/xinetd.conf来设置,里面为一些默认设置,既访问此窗口的基本要求,像要有身份证啊,啥的,然后每个具体的服务也会有自己的一些社会自,这些设置在/etc/xinet.d/中都有相应的设置文件的。详述超级守护进程和它的配置文件&&&& 利用超级守护进程来管理(网络)服务的最大好处是&安全性较高&。因为超级守护进程可以通过额外的数据分析,来管理谁可以,谁不可以使用某项服务。类似于多了一层防火墙的机制,确保了安全性。&&&& 挂在xinetd例的服务设置项目写在/etc/xinetd.conf与/etc/xinetd.d/*目录的任何文件中。&&&&&&&&& 1)/etc/xinetd.conf:设置xinetd服务的默认参数文件&&&& # ......&&&& defaults&&&& {&&&& # Please note that you need a log_type line to be able to use log_on_success&&&& # and log_on_failure. The default is the following :&&&& # log_type = SYSLOG daemon info&&&& instances = 60&&&&&&&&&&&&&&&&&&&&&&&&& # 同一服务的同时联机最多60台&&&& log_type = SYSLOG authpriv&&&& # 登录后会记录到文件中的信息&&&& log_on_success = HOST PID&&&& # 成功登录时,会记录的信息有哪些&&&& log_on_failure = HOST&&&&&&&&&&&&& # 若登录失败,记录的信息是什么&&&& cps = 25 30&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& # 同一秒内最大联机数量为25台,若超过25台,则该服务会暂停30秒&&&& }&&&& includedir /etc/xinetd.d&&&&&&&&&&&&& # 在此目录中,挂靠的服务可以有自己的参数,如果没有定义,则遵守上面的配置&&&&&&&& 2)/etc/xinetd.d/*:这个目录里面的文件都是挂上xinetd的所有服务,如telnet、pop3等。&&&& 以telnet服务为例,它的配置文件如下。&&&& # default: on&&&&& # description: The telnet server se it uses \&&&&& # unencrypted username/password pairs for authentication.&&&&& service telnet&&&&& {&&&&&&&& disable = no&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& # 开关,该服务可以进行开启&&&&&&& only_from = 192.168.1.0/24&&&&&&&&&&&& # 仅允许来自网段192.168.1.0/24的连接&&&&&&& no_access = 192.168.1.3&&&&&&& flags = REUSE&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& #& 额外的参数使用REUSE&&&&&&& socket_type = stream&&&&&&&&&&&&&&&&&&&&&& # 联机使用的数据包是TCP,如果为dgram,则使用UDP&&&&&&& wait = no&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& # 多线程方式,多个请求同时启动&&&&&&& user = flagonxia&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& # 启动者默认为flagonxia&&&&&&& server = /usr/sbin/in.telnetd&&&&&&&&&&&& # 服务的启动程序文件的完整路径名&&&&&&& log_on_failure += USERID&&&&&&&&&&&&&&&& # 失败后,syslog记录的项目}[1]&&&
【声明】:黑吧安全网()登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱,我们会在最短的时间内进行处理。
上一篇:【】【】Linux进程理解与实践(五)细谈守护进程
一. 守护进程及其特性
守护进程最重要的特性是后台运行。在这一点上DOS下的常驻内存程序TSR与之相似。其次,守护进程必须与其运行前的环境隔离开来。这些环境包括未关闭的文件描述符,控制终端,会话和进程组,工作目录以及文件创建掩模等。这些环境通常是守护进程从执行它的父进程(特别是shell)中继承下来的。最后,守护进程的启动方式有其特殊之处。它可以在启动时从启动脚本/etc/rc.d中启动,可以由作业规划进程crond启动,还可以由用户终端(通常是shell)执行。
总之,除开这些特殊性以外,守护进程与普通进程基本上没有什么区别。因此,编写守护进程实际上是把一个普通进程按照上述的守护进程的特性改造成为守护进程。如果读者对进程有比较深入的认识就更容易理解和了。
二. 守护进程的编程要点
前面讲过,不同Unix环境下守护进程的编程规则并不一致。所幸的是守护进程的编程原则其实都一样,区别在于具体的实现细节不同。这个原则就是要满足守护进程的特性。同时,Linux是基于Syetem V的SVR4并遵循Posix标准,实现起来与BSD4相比更方便。编程要点如下;
1. 在后台运行。
为避免挂起控制终端将Daemon放入后台执行。方法是在进程中调用fork使父进程终止,让Daemon在子进程中后台执行。
if(pid=fork())
exit(0);//是父进程,结束父进程,子进程继续
2. 脱离控制终端,登录会话和进程组
有必要先介绍一下Linux中的进程与控制终端,登录会话和进程组之间的关系:进程属于一个进程组,进程组号(GID)就是进程组长的进程号(PID)。登录会话可以包含多个进程组。这些进程组共享一个控制终端。这个控制终端通常是创建进程的登录终端。
控制终端,登录会话和进程组通常是从父进程继承下来的。我们的目的就是要摆脱它们,使之不受它们的影响。方法是在第1点的基础上,调用setsid()使进程成为会话组长:
setsid函数用于创建一个新的会话,并担任该会话组的组长。调用setsid有下面的3个作用:
(1)让进程摆脱原会话的控制
(2)让进程摆脱原进程组的控制
(3)让进程摆脱原控制终端的控制
也就是说由于创建守护进程的第一步调用了fork函数来创建子进程,再将父进程退出。由于在调用了fork函数时,子进程全盘拷贝了父进程的会话期、进程组、控制终端等,虽然父进程退出了,但会话期、进程组、控制终端等并没有改变,因此,这还不是真正意义上的独立开来,而setsid函数能够使进程完全独立出来,从而摆脱其他进程的控制。
说明:当进程是会话组长时setsid()调用失败。但第一点已经保证进程不是会话组长。setsid()调用成功后,进程成为新的会话组长和新的进程组长,并与原来的登录会话和进程组脱离。由于会话过程对控制终端的独占性,进程同时与控制终端脱离。 3. 禁止进程重新打开控制终端
现在,进程已经成为无终端的会话组长。但它可以重新申请打开一个控制终端。可以通过使进程不再成为会话组长来禁止进程重新打开控制终端:
if(pid=fork())
exit(0);//结束第一子进程,第二子进程继续(第二子进程不再是会话组长)
注意:很多读者就会问,为什么要创建两次进程呢? 这是因为第二步结束后,进程创建了一个新的会话组,并成为会话组长,而会话组长可能获得控制终端,如果获得了控制终端那么或这个进程就不是守护进程了。所以添加了这几句代码,让进程失去会话组长的身份,从而没有获得控制终端的权限。
4. 关闭打开的文件描述符
同文件权限码一样,用fork函数新建的子进程会从父进程那里继承一些已经打开了的文件。这些被打开的文件可能永远不会被守护进程读写,但它们一样消耗系统资源,而且可能导致所在的文件系统无法卸下。 在上面的第二步之后,守护进程已经与所属的控制终端失去了联系。因此从终端输入的字符不可能达到守护进程,守护进程中用常规方法(如printf)输出的字符也不可能在终端上显示出来。所以,文件描述符为0、1和2 的3个文件(常说的输入、输出和报错)已经失去了存在的价值,也应被关闭。通常按如下方式关闭文件描述符: for(i=0;i5. 改变当前工作目录
这一步也是必要的步骤。使用fork创建的子进程继承了父进程的当前工作目录。由于在进程运行中,当前目录所在的文件系统(如&/mnt/usb&)是不能卸载的,这对以后的使用会造成诸多的麻烦(比如系统由于某种原因要进入单用户模式)。因此,通常的做法是让&/&作为守护进程的当前工作目录,这样就可以避免上述的问题,当然,如有特殊需要,也可以把当前工作目录换成其他的路径,如/tmp。改变工作目录的常见函数式chdir。
6. 重设文件创建掩模
进程从创建它的父进程那里继承了文件创建掩模。它可能修改守护进程所创建的文件的存取位。为防止这一点,将文件创建掩模清除:umask(0);
7. 处理SIGCHLD信号
处理SIGCHLD信号并不是必须的。但对于某些进程,特别是服务器进程往往在请求到来时生成子进程处理请求。如果父进程不等待子进程结束,子进程将成为僵尸进程(zombie)从而占用系统资源。如果父进程等待子进程结束,将增加父进程的负担,影响服务器进程的并发性能。在Linux下可以简单地将SIGCHLD信号的操作设为SIG_IGN。
signal(SIGCHLD,SIG_IGN);
这样,内核在子进程结束时不会产生僵尸进程。这一点与BSD4不同,BSD4下必须显式等待子进程结束才能释放僵尸进程。
因为linux里的进程都属于一颗树,树的根结点是linux系统初始化结束阶段时启动的init进程,这个进程的pid是1,所有的其他进程都是它的子孙。除了init,任何进程一定有他的父进程,而父进程会负责分配(fork)、回收(wait4)它申请的进程资源。这个树状关系也比较健壮,当某个进程还在运行时,它的父进程却退出了,这个进程却没有成为孤儿进程,因为linux有一个机制,init进程会接管它,成为它的父进程。这也是守护进程的由来了,因为守护进程的其中一个要求就是希望init成为守护进程的父进程。
如果某个进程自身终止了,在调用exit清理完相关的内容文件等资源后,它就会进入ZOMBIE状态,它的父进程会调用wait4来回收这个task_struct,但是,如果父进程一直没有调用wait4去释放子进程的task_struct,问题就来了,这个task_struct谁来回收呢?永远没有人,除非父进程终止后,被init进程接管这个ZOMBIE进程,然后调用wait4来回收进程描述符。如果父进程一直在运行着,这个ZOMBIE会永远的占用系统资源,用KILL发任何信号量也不能释放它。这是很可怕的,因为服务器上可能会出现无数ZOMBIE进程导致机器挂掉。
8.守护进程退出处理
当用户需要外部停止守护进程运行时,往往会使用 kill命令停止该守护进程。所以,守护进程中需要编码来实现kill发出的signal信号处理,达到进程的正常退出。
===============================
signal(SIGTERM, sigterm_handler);
void sigterm_handler(int arg)
_running = 0;
===============================
这样,一个简单的守护进程就建立起来了。
#include & unistd.h &
#include & signal.h &
#include & sys/param.h &
#include & sys/types.h &
#include & sys/stat.h &
void init_daemon(void)
if(pid=fork())
exit(0);//是父进程,结束父进程
else if(pid& 0)
exit(1);//fork失败,退出
//是第一子进程,后台继续执行
setsid();//第一子进程成为新的会话组长和进程组长
//并与控制终端分离
if(pid=fork())
exit(0);//是第一子进程,结束第一子进程
else if(pid& 0)
exit(1);//fork失败,退出
//是第二子进程,继续
//第二子进程不再是会话组长
for(i=0;i& NOFILE;++i)//关闭打开的文件描述符
chdir(&/tmp&);//改变工作目录到/tmp
umask(0);//重设文件创建掩模
2. test.c清单
#include & stdio.h &
#include & time.h &
void init_daemon(void);//守护进程初始化函数
init_daemon();//初始化为Daemon
while(1)//每隔一分钟向test.log报告运行状态
sleep(60);//睡眠一分钟
if((fp=fopen(&test.log&,&a&)) &=0)
t=time(0);
fprintf(fp,&Im here at %s/n&,asctime(localtime(&t)) );
fclose(fp);
查看进程:ps -ef
从输出可以发现test守护进程的各种特性满足上面的要求。
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467142',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'daemon 进程为什么要fork两次,与后台运行程序区别?
daemon 进程为什么要fork两次,与后台运行程序区别?
&daemon进程是后台守护进程.linux 下server都是daemon进程。相信大部分开发人员都知道如何去写一个daemon进程。但是另一方面,大部分人不知道为什么要这么做,不少人是从某个地方copy一个函数。但是具体为什么这么实现,却不是很透彻。daemon函数存在的原因是因为控制终端由于某些原因(如断开终端链接)会发送一些信号的原因。而接收进城处理这些信号缺省动作会让进程退出。这些信号会由于终端上敲一些特殊按键而产生。
贴一个daemon函数常见的实现:
int daemon(void) {
pid_t pid = fork();
if( pid != 0 ) exit(0);//parent
//first children
if(setsid() == -1)
printf(&setsid failedn&);
assert(0);
pid = fork();
if( pid != 0) exit(0);
//second children
chdir (&/&);
for (int i = 0; i & 3; i++)
close (i);
int stdfd = open (&/dev/null&, O_RDWR);
dup2(stdfd, STDOUT_FILENO);
dup2(stdfd, STDERR_FILENO);
return 0; }
<span style="color:# 、第一次fork的作用是让shell 认为本条命令 已经终止,不用挂在终端输入上。还有一个作用是为后面setsid服务。setsid的调用者不能是进程组组长(group leader).
此时父进程是进程组组长。
2 、setsid() 是本函数最重要的一个调用。它完成了daemon函数想要做的大部分事情。调用完整个函数。子进程是会话组长(sid==pid),也是进程组组长(pgid == pid),并且脱离了原来控制终端。到了这一步,基本上不管控制终端如何怎么样。新的进程都不会收到那些信号。
3 &、经过前面2个步骤,基本想要做的都做了。第2次fork不是必须的。也看到很多开源服务没有fork第二次。fork第二次主要目的是。防止进程再次打开一个控制终端。因为打开一个控制终端的前提条件是该进程必须是会话组长。再fork一次,子进程ID != sid(sid是进程父进程的sid)。所以也无法打开新的控制终端。
& & daemon目的就是防止终端产生的一些信号让进程退出。上面函数并没有直接调用signal函数去处理它。而是间接通过fork和setsid函数使用更少代码优雅处理。而被有些人误以为是僵死进程的原因需要这样处理。
& & 当然,也有很多程序不是像上面函数那样去实现。而是直接通过忽略信号方式处理。这样其实也不错,因为这些信号很少会有用到的价&#20540;。直接忽略基本上不存在误杀的情况。反正达到最终目的就可以。条条大路通罗马。
& &下面罗列一下控制终端会产生哪些信号。程序中只要处理好这些信号,同样能达到上面函数实现的目的。
& &//后台进程读取/写入终端输入产生下面两个信号,或者控制终端不存在情况读取和写入会产生
& &signal(SIGTTOU, SIG_IGN);
& &signal(SIGTTIN, SIG_IGN);
& &//按CTRL-C ,CTRL- CTRL-Z会向前台进程组发送下面这些信号
& &signal(SIGINT, &SIG_IGN );
& &signal(SIGQUIT, SIG_IGN );
& &signal(SIGTSTP, SIG_IGN );
& &//终端断开,会给会话组长或孤儿进程组所有成员发送下面信号
& &signal(SIGHUP, &SIG_IGN );
& &还有有些信号也可以由终端shell产生,需要关注
& &signal(SIGCONT, SIG_IGN );
& &signal(SIGSTOP, SIG_IGN );
& 上面这些信号,应该有些程序缺省处理(SIG_DFL)本身动作就是忽略(SIG_IGN),不是退出进程。不过按照上面写也不会造成什么问题。
dup2(stdfd, STDOUT_FILENO) 是将该程序的标准输出重定向到了黑洞,dup和dup2都可用来复制一个现存的文件描述符,使两个文件描述符指向同一个file结构体
#include &unistd.h&
int dup(int newfd);
int dup2(int newfd, int oldfd);
下面用一个简单的例子解释两个函数的用法和区别:
#include &unistd.h& #include &sys/stat.h& #include &fcntl.h& #include &stdio.h& #include &stdlib.h& #include &string.h&
int main(void)
int fd, save_
char msg[] = &This is a test of dup() & dup2()n&;
fd = open(&somefile&, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);
if(fd&0) {
perror(&open&);
save_fd = dup(STDOUT_FILENO);
//运行后save_fd指向STDOUT——FILENO,即save_fd指向标准输出
printf(&save_fd=%dn&,save_fd);
test=dup2(fd, STDOUT_FILENO);
//运行后STDOUT_FILENO指向fd所指向的文件,即STDOUT_FILENO指向somefile
printf(&dup2_1=%dn&,test);
//测试用 此时的标准输出不再指向显示器,因此该段测试将写入somefile文件中
close(fd);
write(STDOUT_FILENO, msg, strlen(msg));
//此时STDOUT_FILENO所指向的是somefile文件不再是标准输出流,因此该段将
//写入somefile文件中
test=dup2(save_fd, STDOUT_FILENO);
//运行后STDOUT_FILENO指向save_fd所指向的文件,即标准输出流
printf(&dup2_2=%dn&,test);
//测试用 此时标准输出流重新指回显示器,因此该段测试将写入显示器
write(STDOUT_FILENO, msg, strlen(msg));
//此时STDOUT_FILENO所指向的便回标准输出流该段将写入显示器
close(save_fd);
守护进程与用&结尾的后台运行程序有什么区别呢?
最大的区别有几点:
1)守护进程已经完全脱离终端控制台了,而后台程序并未完全脱离终端,在终端未关闭前还是会往终端输出结果
2)守护进程在关闭终端控制台时不会受影响,而后台程序会随用户退出而停止,需要在以nohug xxx & &#26684;式运行才能避免影响
3)守护进程的会话组和当前目录,文件描述符都是独立的。后台运行只是终端进行了一次fork,让程序在后台执行,这些都没改变。
感谢关注 Ithao123Linux频道,是专门为互联网人打造的学习交流平台,全面满足互联网人工作与学习需求,更多互联网资讯尽在 IThao123!
Laravel是一套简洁、优雅的PHP Web开发框架(PHP Web Framework)。它可以让你从面条一样杂乱的代码中解脱出来;它可以帮你构建一个完美的网络APP,而且每行代码都可以简洁、富于表达力。
Hadoop是一个由Apache基金会所开发的分布式系统基础架构。
用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。
Hadoop实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS。HDFS有高容错性的特点,并且设计用来部署在低廉的(low-cost)硬件上;而且它提供高吞吐量(high throughput)来访问应用程序的数据,适合那些有着超大数据集(large data set)的应用程序。HDFS放宽了(relax)POSIX的要求,可以以流的形式访问(streaming access)文件系统中的数据。
Hadoop的框架最核心的设计就是:HDFS和MapReduce。HDFS为海量的数据提供了存储,则MapReduce为海量的数据提供了计算。
产品设计是互联网产品经理的核心能力,一个好的产品经理一定在产品设计方面有扎实的功底,本专题将从互联网产品设计的几个方面谈谈产品设计
随着国内互联网的发展,产品经理岗位需求大幅增加,在国内,从事产品工作的大部分岗位为产品经理,其实现实中,很多从事产品工作的岗位是不能称为产品经理,主要原因是对产品经理的职责不明确,那产品经理的职责有哪些,本专题将详细介绍产品经理的主要职责
IThao123周刊

我要回帖

更多关于 linux 守护进程 的文章

 

随机推荐