LINUX系统编程 由REDIS的持久化机制联想到的子进程退出的相关问题

19:22:01 2014-08-27

引言:

以前对wait waitpid 以及exit这几个函数只是大致上了解,但是看REDIS的AOF和RDB 2种持久化时 均要处理子进程运行完成退出和父进程需要做的什么事情,所以特定看了UNIX环境编程和LINUX系统编程这2本书 重新梳理下整个要点。

内容:

一般而言: 如果程序类似于下面的情况:

if((pid=fork())==0)
{
  dochildtthing();
 exit(0);
}
else if(pid>0)
{
 dofathertthing();
}

  子进程就会调用了我们进程退出系统调用exit()分为2种状态  0: 成功  非0:失败

  exit需要做以下事情:

  1: 关闭所有打开的IO流

  2 删除所有的临时文件

  1 2是传说中用户态需要完成的事情  接下来就调用_exit() 【这个函数在用户态下 是被exit()封装起来的函数】触发内核来完成进程退出的相关工作

  接下来就是清空所有的子进程所需要的资源哦 最后完成了 就会发送一个进程退出状态【信号】给父进程  父进程做什么处理就是编程人员完成的。

子进程发送的信号是SIGCHLD 一般而言就像REDIS fork()了一个进程之后  子进程完成了相应的持久化动作之后,父进程需要了解子进程一些状态来做相应的处理工作,所以在LINUX系统中,这个子进程退出后 还有一个标记位 我们称作zombie进程。父进程必须来取子进程的相应zombie的相应标记信息 不然是不会消除的。

所以对于父进程而言,必须调用相应的函数【首先是注册了SIGCHLD】处理这些标记位哦  wait/waitpid就是干这种事情。我们来看看这系列的调用所要做的事情:

 1 #include <unistd.h>
 2 #include <stdio.h>
 3 #include <sys/types.h>
 4 #include <sys/wait.h>
 5 #include <stdlib.h>
 6
 7 int main()
 8 {
 9     int status;
10     pid_t pid;
11     if(fork()==0)
12     {
13         abort();
14     }
15     pid=wait(&status);
16     printf("pid=%d\n",pid);
17     if(WIFEXITED(status))
18         printf("正常退出\n");
19     if(WIFSIGNALED(status))
20         printf("killed by signal\n");
21     return 0;
22 }

wait等待子进程挂  结果可以读出子进程是被信号量终止了  所以说 读出子进程的状态还是非常有实际意义的~!

接下来看看wait/waitpid函数的区别:

如果有多个子进程 我该怎么办  要么选择多个wait 但是同时到达 可能就会处理一个子进程 而其他进程状态没有被处理  造成了很多zombie进程 这是不行的 这样就有了waitpid函数:

waitpid(pid_t pid,int *status,int options)

pid=-1  等待任意一子进程

>0  要传入的那个子进程

参数:

WNOHANG: 不会阻塞  立刻返回。 其他参数暂时不去研究了

这样如果有这种 while(waitpid(-1,&stat,WNOHANG)>0);

这样就能接受到所有的子进程的SIGCHLD了。 wait只执行一次 而Linux信号不排队 同时到达 也只会处罚一次哦 这个必须要了解 这样通过waitpid循环来解决掉,但是如果不指定WNOHANG的话  又比较麻烦  主进程会阻塞 这不是我们所想要的哦 所以必须解阻塞。

时间: 2024-10-12 23:22:09

LINUX系统编程 由REDIS的持久化机制联想到的子进程退出的相关问题的相关文章

Redis源码剖析和注释(十八)--- Redis AOF持久化机制

Redis AOF持久化机制 1. AOF持久化介绍 Redis中支持RDB和AOF这两种持久化机制,目的都是避免因进程退出,造成的数据丢失问题. RDB持久化:把当前进程数据生成时间点快照(point-in-time snapshot)保存到硬盘的过程,避免数据意外丢失. AOF持久化:以独立日志的方式记录每次写命令,重启时在重新执行AOF文件中的命令达到恢复数据的目的. Redis RDB持久化机制源码剖析和注释 AOF的使用:在redis.conf配置文件中,将appendonly设置为y

Linux系统编程-setitimer函数

功能:linux系统编程中,setitimer是一个经常被使用的函数,可用来实现延时和定时的功能. 头文件:sys/time.h 函数原型: int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value); 参数含义: 1.which参数用来设置定时器类型,可选的值为 (1)ITIMER_REAL : 设置定时器以系统真实所花费的时间来计时,运行指定时间后发送SIGALRM信号. (

Redis数据持久化机制AOF原理分析二

Redis数据持久化机制AOF原理分析二 分类: Redis 2014-01-12 15:36  737人阅读  评论(0)  收藏  举报 redis AOF rewrite 目录(?)[+] 本文所引用的源码全部来自Redis2.8.2版本. Redis AOF数据持久化机制的实现相关代码是redis.c, redis.h, aof.c, bio.c, rio.c, config.c 在阅读本文之前请先阅读Redis数据持久化机制AOF原理分析之配置详解文章,了解AOF相关参数的解析,文章链

linux系统编程之管道(一):匿名管道(pipe)

原文地址:http://www.cnblogs.com/mickole/p/3192210.html 一,什么是管道 管道是Linux支持的最初Unix IPC形式之一,具有以下特点: 管道是半双工的,数据只能向一个方向流动:需要双方通信时,需要建立起两个管道: 只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程): 单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中. 数据的读

Linux系统编程札记:进程通信(一) &nbsp; &nbsp;

进程简单来讲就是一个程序的一次执行,这里说的进程一般都指的是运行在用户态的进程,而处于用户态的不同进程之间是彼此相互隔离的,它们必须通过某种方式来进行通信,具体理由如下: (1)数据传输:有时候一个进程需要将它的数据发送给另一个进程. (2)资源共享:有时候多个进程之间需要共享同样的资源. (3)通知事件:有时候一个进程需要向另一个或一组进程发送消息,通知它们发生了某个事件. (4)进程控制:有些进程希望能够完全控制另一个进程的执行,此时控制进程希望能够拦截另一进程的所有操作,并能够及时知道它的

嵌入式 Linux系统编程(三)——标准IO库

嵌入式 Linux系统编程(三)--标准IO库 与文件IO函数相类似,标准IO库中提供的是fopen.fclose.fread.fwrite等面向流对象的IO函数,这些函数在实现时本身就要调用linux的文件IO这些系统调用. 一.标准IO库函数的缓冲机制 由于IO设备的访问速度与CPU的速度相差好几个数量级,为了协调IO设备与CPU的速度的不匹配,对于块设备,内核使用了页高速缓存,即数据会先被拷贝到操作系统内核的页缓存区中,然后才会从操作系统内核的缓存区拷贝到应用程序的地址空间. 当应用程序尝

Linux系统编程_2_文件I/O

这里说的的文件I/O指的是不带缓存的: 1.关于带缓存的IO操作和不带缓存的IO操作,参见另一篇文章: 带缓存IO和不带缓存IO详解 Linux中的文件IO(不带缓存的IO)通常用的有以下几个: open    read    write    lseek   close 2.open的参数 int fd(filename, mode); mode 通常可以是O_RDONLY(只读)  O_WRONLY(只写)  O_RDWR(读写) 必须指定且只能指定一个! 其他的可供选择,可通过或运算添加:

嵌入式 Linux网络编程(四)——Select机制

嵌入式 Linux网络编程(四)--Select机制 一.select工作机制 poll和select,都是基于内核函数sys_poll实现的,不同在于在linux中select是从BSD Unix系统继承而来,poll则是从SYSTEM V Unix系统继承而来,因此两种方式相差不大.poll函数没有最大文件描述符数量的限制.poll和 select与一样,大量文件描述符的数组被整体复制于用户态和内核的地址空间之间,开销随着文件描述符数量的增加而线性增大. select需要驱动程序的支持,驱动

Linux系统编程【转】

转自:https://blog.csdn.net/majiakun1/article/details/8558308 一.Linux系统编程概论 1.1 系统编程基石 syscall: libc:标准C库.系统调用封装.线程库.基本应用工具 gcc: 1.2 模块接口 API:应用程序编程接口,源代码级别,能通过编译,由标准C语言定义,libc来实现 ABI:应用程序二进制接口,二进制级别,能正常运行,关注调用约定.字节序.寄存器使用.系统调用.链接.二进制格式等,很难实现 1.3 错误处理 <