linux第1天 fork exec 守护进程
概念方面
文件是对I/O设备的抽象表示、虚拟存储器是对主存和磁盘I/O设备的抽象表示、进程则是对处理器、主存和I/O设备的抽象表示
中断
早期是没有进程这个概念,当出现中断技术以后才出现进程这个概念
分式操作系统
基于时间片轮转
进程是操作系统对资源的一种抽象,一个进程:代码段、数据段、堆栈段、+进程控制块(PCB)
PCB是操作系统感知进程存在的一个重要数据结构(cpu通过进程控制块来控制进程)
fork()
使用fork函数得到的子进程从父进程的继承了整个进程的地址空间,包括:进程上下文、进程堆栈、内存信息、打开的文件描述符、信号控制设置、进程优先级、进程组号、当前工作目录、根目录、资源限制、控制终端等,,进程PCB控制块。
子进程与父进程的区别在于:
1、父进程设置的锁,子进程不继承
2、各自的进程ID和父进程ID不同
3、子进程的未决告警被清除;
4、子进程的未决信号集设置为空集。
理解1:fork系统调用之后,父子进程将交替执行。
理解2:怎么样理解一次调用2次返回? 父子进程将在各自的进程空间里返回.
理解3:怎么样理解,fork返回值大于零的是父进程,为什么这样设计:?通过子进程获取父进程简单getppid(),而通过父进程获取子进程麻烦,还不如把子进程pid设置为0
理解4:怎么样理解分支在fork之后,而不是父进程main函数的开始?子进程继承父进程的.进程上下文、进程堆栈、内存信息、打开的文件描述符、信号控制设置、进程优先级、进程组号、当前工作目录、根目录、资源限制、控制终端等,,进程PCB控制块。
写时复制copy on write
如果多个进程要读取它们自己的那部分资源的副本,那么继承时复制是不必要的。
每个进程只要保存一个指向这个不需要写入数据的资源的指针就可以了。
如果一个进程要修改自己的那份资源的“副本”,那么就会复制那份资源对应的页。这就是写时复制的含义
原因分析:加快速度,linux内核是段页式管理机制(因段管理从0开始,),也可叫页式管理机制。只复制对应的页。缺页,在中断查询,再赋值。
对父进程打开的文件,子进程也会继承过来.然后被打开的文件中,文件表中refcnt引用加1
对于信号方面,子进程继承阻塞信号设置,但要抛弃父进程的未决信号集
fork和vfork
|
1)在fork还没实现copy on write之前。Unix设计者很关心fork之后立刻执行exec所造成的地址空间浪费,所以引入了vfork系统调用。 2)vfork有个限制,子进程必须立刻执行_exit或者exec函数。 即使fork实现了copy on write,效率也没有vfork高,但是我们不推荐使用vfork,因为几乎每一个vfork的实现,都或多或少存在一定的问题。 |
|
结论: 1:fork子进程拷贝父进程的数据段 Vfork子进程与父进程共享数据段; 2:fork父、子进程的执行次序不确定 Vfork:子进程先运行,父进程后运行; |
exec函数族
execve替换进程映像(加载程序)注意execve是一个系统调用;
替换意味着:代码段、数据段、堆栈段、进程控制块PCB全部替换。
int main(void)
{
int fd;
pid_t pid;
signal(SIGCHLD, SIG_IGN);//不接收SIGCHILD信号,父进程关闭会子进程直接给1号进程管制
printf("befor fork pid:%d \n", getpid()); g_num = 10; pid = vfork();//不稳定,退出时可能会出现错误.
if (pid == -1)
{
printf("pid < 0 err.\n");
return -1;
} if (pid > 0)
{
printf("parent: pid:%d \n", getpid());
}
else if (pid == 0)
{
printf("child: %d, parent: %d \n", getpid(), getppid()); char *const argv[] = {"ls", "-lt", NULL};
execve("/bin/ls", argv, NULL); //注意:此处有/bin/ls程序结束程序,不会出现coredump现象 printf("测试下面这句话还执行吗\n");
//exit(0);
//1 vfork只有需要用exit(0) _exit(0)
//2 测试return 0; 区别
} printf("fork after....\n");
return 0;
}
进程终止的5种方式
正常退出
从main函数返回
调用exit 会清空缓冲区,再调用内核中的退出函数
调用_exit 直接调用内核中的退出函数
异常退出
调用abort 产生SIGABOUT信号 强制关闭
由信号终止 ctrl+c SIGINT 强制关闭
atexit可以注册终止处理程序,ANSI C规定最多可以注册32个终止处理程序,它其实也是一个回调函数,传入的是函数指针
exec关联的函数族
q 包含头文件<unistd.h>
q 功能用exec函数可以把当前进程替换为一个新进程。exec名下是由多个关联函数组成的一个完整系列,头文件<unistd.h>
q 原型
/*
#include <unistd.h>
extern char **environ;
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...); PATH
int execle(const char *path, const char *arg,
..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
|
以execlp、execvp、和execle讲解 path参数表示你要启动程序的名称包括路径名 arg参数表示启动程序所带的参数 返回值:成功返回0,失败返回-1 |
|
execl,execlp,execle(都带“l”)的参数个数是可变的,参数以一个空指针结束。 execv和execvp的第二个参数是一个字符串数组,新程序在启动时会把在argv数组中给定的参数传递到main 这些函数通常都是用execve实现的,这是一种约定俗成的做法,并不是非这样不可。 |
|
名字最后一个字母是“p”的函数会搜索PATH环境变量去查找新程序的可执行文件。如果可执行文件不在PATH定义的路径上,就必须把包括子目录在内的绝对文件名做为一个参数传递给这些函数 总结:l代表可变参数列表,p代表在path环境变量中搜索file文件。envp代表环境变量。 |
int main(void)
{
//演示程序被完全替换
//替换以后,pid不会发生变化
//注意 printf后的\n不能忘记,不然main函数打印不出来,
//因为 \n 具有清除缓冲区的作用
printf(“main getpid: %d\n”, getpid()); //execlp(“ls”, “ls”, “-lt”, NULL);
int ret = execlp(“./testpid2”, NULL, NULL);
if (ret == -1)
{
perror(“ERR: “);
} printf(“fork after….\n”);
return 0;
}
extern char **environ;//由内核分配内存,内存的第三种模型, 有关环境变量
int main(int argc, char *argv[])
{
printf(“main egin…\n”);
//1)如果envp环境参数列表不填写,则testpidandenv程序会使用默认的环境参数列表
//2)如果envp环境参数列表填写,则testpidandenv程序会使用你填写的环境参数列表
char *ars[] = {“aa=111”, “bb==222”, NULL}; int ret = execle(“./testpidandenv”,”testpidandenv”, NULL,NULL);
//int ret = execle(“./testpidandenv”,”testpidandenv”, NULL,ars); if (ret == -1)
{
perror("main:");
}
printf("main end...\n");
return 0;
}
关于守护进程相关知识,顺便加强一下shell知识
当我们用telnet登陆linux服务器,验证好帐号密码之后,会建立一个会话期(session),同时服务器会运行一个shell,针对登陆上的帐户而言
此时,我们在这个终端上运行的所有程序命令都基于这个会话期,一旦终端关闭,运行于这个会话期的所有程序都会关闭,linux内核提供了一个函数setsid
脱离了终端,脱离了这个session,就像WINDOWS的服务程序一样,驻留在linux中,故名思议,守护进程.
注:调用setsid的不能是进程组长(一般为父进程),通常的做法是fork一个子进程,然后再调用setsid,
调用之后,需要改变当前路径为根路径,因为程序启动时,是与启动路径绑定的,如果不改变,将来要对启动路径作某些更改的时候,会失败.
另外还需要将标准输入,输出,错误文件描述符都重定项到"dev/null",避免资源浪费
linux第1天 fork exec 守护进程的更多相关文章
- Linux学习笔记(9)-守护进程
明天学这个!! ---------------------------------------------------------- 守护进程(Daemon)是运行在后台的一种特殊进程.它独立于控制终 ...
- Linux系统编程(26)——守护进程
Linux系统启动时会启动很多系统服务进程,比如inetd,这些系统服务进程没有控制终端,不能直接和用户交互.其它进程都是在用户登录或运行程序时创建,在运行结束或用户注销时终止,但系统服务进程不受用户 ...
- linux c语言学习笔记之守护进程
哈尔滨理工大学软件工程专业08-7李万鹏原创作品,转载请标明出处 http://blog.csdn.net/woshixingaaa/archive/2010/06/06/5651095.aspx 守 ...
- Java实现Linux下服务器程序的双守护进程
作者:Vinkn 来自http://www.cnblogs.com/Vinkn/ 一.简介 现在的服务器端程序很多都是基于Java开发,针对于Java开发的Socket程序,这样的服务器端上线后出现问 ...
- 基于Linux环境,创建PHP后台守护进程(转载)
应用场景:某些情况下,我们需要持续的周期性的提供一些服务,比如监控内存或cpu的运行状况,这些应用与客户端是没有关系的,不是说客户端(如web界面,手机app等)关闭了,我们就不监控内存或cpu了,为 ...
- Linux+Nginx+Asp.net Core及守护进程部署
上篇<Docker基础入门及示例>文章介绍了Docker部署,以及相关.net core 的打包示例.这篇文章我将以oss.offical.site站点为例,主要介绍下在linux机器下完 ...
- 浅析linux 下shell命令执行和守护进程
执行shell脚本有以下几种方式 1.相对路径方式,需先cd到脚本路径下 [root@banking tmp]# cd /tmp [root@banking tmp]# ./ceshi.sh 脚本执行 ...
- Linux系统添加应用服务进程的守护进程
以前曾在Linux上维护应用服务,但是只是简单的迭代版本等工作,没有什么技术含量.最近部署在Linux服务器上的一个平台的总线进程broker(下面总线用broker指代)经常挂掉,由于总线负责服务之 ...
- 对linux中source,fork,exec的理解以及case的 使用
fork 使用 fork 方式运行 script 时, 就是让 shell(parent process) 产生一个 child process 去执行该 script, 当 child proc ...
随机推荐
- 区分总结innerHeight与clientHeight、innerWidth与clientWidth、scrollLeft与pageXOffset等属性
window对象: (1)innerHeight属性:窗口中文档显示区域的高度,不包括菜单栏.工具栏等部分.该属性可读可写. IE不支持该属性,IE中body元素的clientHeight属性与该属性 ...
- Bootstrap 模态框插件
一.基本使用 使用模态框的弹窗组件需要三层 div 容器元素,分别为 modal(模态声明层). dialog(窗口声明层).content(内容层).在内容层里面,还有三层,分别为 header(头 ...
- php内容
PHP语言原理:先把代码显示在源代码中,再通过浏览器解析在网页上 PHP中关键字通常分为四种类型: 1. 用于数据类型定义的关键字,如:int,string,bool,classic,object和a ...
- Java实验报告二:Java面向对象程序设计
Java实验报告二:Java面向对象程序设计 ...
- 【Swing】Swing初步认知
AWT(abstract Window Toolkit) AWT是java发布的第一个图形界面库.AWT通过调用系统本地的库,来创建和显示控件. AWT 的组件都是使用的native code来编写的 ...
- python socket 选项
一.int socket(int domain, int type, int protocol) 1.domain -- 指定使用何种的地址类型 PF_INET, AF_INET: Ipv4网络协议P ...
- WIN 8.1使用常见问题及解决
WIN 8.1正式版64位(cn_windows_8_1_pro_vl_x64_dvd_2971907)使用问题及解决 一.IE11的输入框会变蓝: 如在百度中搜索时,搜索框和按钮均变成蓝色背景, ...
- Wordpress更换编辑器
这里我更换为KindEditor 1.下载插件 https://wordpress.org/plugins/kindeditor-for-wordpress/ 2.启动插件 3.在 设置 – Kind ...
- android常用命令
首先配置好环境变量会比较方便... 大部分sdk提供的工具都在sdk\platform-tools和sdk\tools下,建议配置这两个路径到path 另外aapt工具在sdk\build-tools ...
- Spring整合CXF之发布WebService服务
今天我们来讲下如何用Spring来整合CXF,来发布WebService服务: 给下官方文档地址:http://cxf.apache.org/docs/writing-a-service-with-s ...