文档章节

深入理解子进程/守护进程/进程高可用实现

乐搏学院
 乐搏学院
发布于 2017/02/27 11:13
字数 1289
阅读 3
收藏 0
点赞 0
评论 0

单个进程:

说明: 进程是程序执行的实例,运行过程中,内核会将程序代码载入内存,为程序变量分配内存建立数据结构,记录进程相关信息,可以将其理解为容器,容器内的资源可以动态调整,但容器内的程序只能使用容器内的资源.

 

生成进程:

说明: 类Unix系统提供fork()系统调用,它非常特殊,普通函数调用1次返回1次,但它调用1次返回2次,因为操作系统自动把当前进程(父进程)复制出一份(子进程),然后在父进程和子进程内返回,子进程永远返回0,父进程返回子进程的pid,这样一个父进程可以fork多个子进程,父进程要记下每个子进程的pid,而子进程只需要os.getppid()就可以拿到父进程的pid

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

#!/usr/bin/env python

# -*- coding: utf-8 -*-

"""

#

# Authors: limanman

# OsChina: http://xmdevops.blog.51cto.com/

# Purpose:

#

"""

# 说明: 导入公共模块

import os

# 说明: 导入其它模块

if __name__ == '__main__':

    print 'master process pid(%s) start ...' % (os.getpid())

    pid = os.fork()

    if pid == 0:

        print 'I am a sub process (%s) created by %s.' % (os.getpid(), os.getppid())

    else:

        print 'I (%s) created a sub process (%s)' % (os.getpid(), pid)

说明: 由于os.fork()会返回2次,分别在子进程内返回然后在主进程内返回,所以如上代码if语句的两个判断都会被打印,第一次返回主进程创建了子进程,第二次进入子进程返回被主进程创建.

 

守护进程:

1. 守护进程也称后台进程,要实现后台进程必须使其与其与原运行环境隔离,包括未关闭的文件描述符,控制终端,会话,进程组,工作目录,以及文件创建掩码等等,有时还必须保证单实例运行

wKiom1gAS-myOEioAABNhnMRFWM123.png

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

#!/usr/bin/env python

# -*- coding: utf-8 -*-

"""

#

# Authors: limanman

# OsChina: http://xmdevops.blog.51cto.com/

# Purpose:

#

"""

# 说明: 导入公共模块

import os

import sys

import time

import atexit

from signal import SIGTERM

# 说明: 导入其它模块

class Daemon(object):

    def __init__(self, pidfile='daemon.pid', stdin=os.devnull,

                 stdout='daemon.log', stderr='daemon.log'):

        self.stdin = stdin

        self.stdout = stdout

        self.stderr = stderr

        self.pidfile = pidfile

    def daemonize(self):

        sys.stdout.write('current process => %s, leader process => %s%s' %

                         (os.getpid(), os.getsid(), os.linesep))

        try:

            pid = os.fork()

            if pid != 0:

                sys.exit(0)

        except OSError, e:

            sys.exit(1)

        os.chdir('.')

        os.umask(0)

        os.setsid()

        sys.stdout.write('current process => %s, leader process => %s%s' %

                         (os.getpid(), os.getsid(), os.linesep))

        try:

            pid = os.fork()

            if pid != 0:

                sys.exit(0)

        except OSError, e:

            sys.exit(1)

        sys.stdout.write('current process => %s, leader process => %s' %

                         (os.getpid(), os.getsid(), os.linesep))

        sys.stdout.flush()

        sys.stderr.flush()

        si = file(self.stdin, 'r')

        so = file(self.stdout, 'a+')

        se = file(self.stderr, 'a+')

        os.dup2(si.fileno(), sys.stdin.fileno())

        os.dup2(so.fileno(), sys.stdout.fileno())

        os.dup2(se.fileno(), sys.stderr.fileno())

        atexit.register(self.delpid)

        strpid = ''.join([str(os.getpid()), os.linesep])

        file(self.pidfile, 'w+b').write(strpid)

    def delpid(self):

        os.remove(self.pidfile)

    def start(self):

        try:

            with open(self.pidfile, 'r+b') as f:

                pid = int(f.read().strip())

        except IOError, e:

            pid = None

        if pid:

            msg = 'pidfile %s already exist. Daemon already running?%s'

            sys.stdout.write(msg % (self.pidfile, os.linesep))

            sys.exit(1)

        self.daemonize()

        self.run()

    def stop(self):

        try:

            with open(self.pidfile, 'r+b') as f:

                pid = int(f.read().strip())

        except IOError, e:

            pid = None

        if not pid:

            msg = 'pidfile %s does not exist. Daemon not running?%s'

            sys.stdout.write(msg % (self.pidfile, os.linesep))

            sys.exit(1)

        try:

            while True:

                os.kill(pid, SIGTERM)

                time.sleep(0.1)

        except OSError, e:

            if os.path.exists(self.pidfile):

                self.delpid()

            sys.exit(1)

    def restart(self):

        self.stop()

        self.start()

    def run(self):

        pass

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

#!/usr/bin/env python

# -*- coding: utf-8 -*-

"""

#

# Authors: limanman

# OsChina: http://xmdevops.blog.51cto.com/

# Purpose:

#

"""

# 说明: 导入公共模块

import os

import time

from daemon import Daemon

# 说明: 导入其它模块

class TaskRun(Daemon):

    def __init__(self*args, **kwargs):

        super(TaskRun, self).__init__(*args, **kwargs)

    def run(self):

        with open('running.log''a+b')

            while True:

                timestamp = str(time.time())

                f.write(''.join([timestamp, os.linesep]))

                f.flush()

                time.sleep(1)

if __name__ == '__main__':

    = TaskRun()

    t.start()

 

进程管控:

说明: 在运维开发中很多时候程序BUG导致程序异常退出,crond时间精度上不可控,常常导致一段时间服务不可用,为了增强程序的可用性,可让子进程处理业务,主进程接收子进程SIGCHLD信号,此信号为系统默认信号子进程退出时会主动发送给主进程,主进程只需要捕捉此信号并启动新的子进程接管业务即可实现业务的高可用

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

#!/usr/bin/env python

# -*- coding: utf-8 -*-

"""

#

# Authors: limanman

# OsChina: http://xmdevops.blog.51cto.com/

# Purpose:

#

"""

# 说明: 导入公共模块

import time

import signal

import multiprocessing

# 说明: 导入其它模块

def task(interval):

    for in xrange(5):

        print _

        time.sleep(interval)

    print 'found notice: sub process(%s) exit with error!' % (multiprocessing.current_process())

def signal_handler(sig_num, frame):

    = multiprocessing.Process(target=task, args=(1,))

    p.daemon = True

    p.start()

if __name__ == '__main__':

    = multiprocessing.Process(target=task, args=(1,))

    p.daemon = True

    p.start()

    = signal.signal(signal.SIGCHLD, signal_handler)

    while True:

        signal.pause()

 

 

登录乐搏学院官网http://www.learnbo.com/

或关注我们的官方微博微信,还有更多惊喜哦~

 

本文出自 “满满李 - 运维开发之路” 博客,请务必保留此出处http://xmdevops.blog.51cto.com/11144840/1861815

© 著作权归作者所有

共有 人打赏支持
乐搏学院
粉丝 6
博文 526
码字总数 707467
作品 0
丰台
程序员
【原创】服务器开发之 Daemon 和 Keepalive

由于业务开发需要,需要对数据库代理进行研究,在研究 MySQL Proxy 实现原理的过程中,对一些功能点进行了分析总结。本文主要讲解下 MySQL Proxy 的 daemon 和 keepalive 功能实现原理。 My...

摩云飞 ⋅ 2013/03/24 ⋅ 5

fork函数替换为SylixOS进程技术笔记

1、使用范围 SylixOS是一款为嵌入式系统设计的硬实时系统。为了保证系统的实时性,系统创建子进程时不做页表切换(页表切换很耗时间,不利于实时性的体现),即父子进程共享同一个页表,而对...

张荣荣123 ⋅ 2017/02/06 ⋅ 0

Java 多线程回顾

做java web开发,一直以来比较依赖java框架和oracle数据库的功能。因为一般遇到高并发的情况并不多,企业内软件多半用户数不多,即使偶尔遇到,也都在oracle数据库中处理了。 对java的多线程...

五大三粗 ⋅ 2015/11/25 ⋅ 0

守护进程daemon详解

一:守护进程概述 Linux Daemon(守护进程)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。它不需要用户输入就能运行而且提供某种服务,...

随性_ ⋅ 2016/07/15 ⋅ 0

深入理解Linux操作系统守护进程的意义

ntsysv 界面如图1所示的窗口,下面详细介绍一下各项系统服务的功能。以英文字母为序: 一、Linux守护进程简介 alsasound :Alsa声卡驱动守护程序。Alsa声卡驱动程序本来是为了 一种声卡Gravi...

JavaGG ⋅ 2009/05/07 ⋅ 0

【Linux】Linux系统编程入门

作者:不洗碗工作室 - Marklux 出处:marklux.cn/blog/56 版权归作者所有,转载请注明出处 文件和文件系统 文件是linux系统中最重要的抽象,大多数情况下你可以把linux系统中的任何东西都理解...

不洗碗工作室 ⋅ 2017/11/14 ⋅ 0

Linux 守护进程原理

Linux系统中的守护进程是一种运行在后台的进程。而守护进程,也就是通常说的Daemon进程。它通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。linux大多数服务器进程就是...

China_OS ⋅ 2013/04/10 ⋅ 0

基于LVS-DR模型实现keepalived的主从架构

在一个系统中,常常存在一些单点服务器,为了提高整个系统的稳定性,我们常常需要对这些单点服务做高可用配置,keepalived即为一种常用的高可用配置服务。 首先我们来了解一下神马是keepali...

MRUJ ⋅ 2017/11/08 ⋅ 0

从零开始UNIX环境高级编程(8):进程控制

1. 进程标识 1.1 进程ID 由于每个进程ID都是唯一的,Unix使用进程ID作为进程的标识。使用ps命令可以查看进程的ID。 系统中还会有一些专用进程ID: ID为0:调度进程(也称交换进程),是内核的一...

伤口不该结疤 ⋅ 2017/05/01 ⋅ 0

[Linux]守护进程详解

在linux或者unix操作系统中在系统的引导的时候会开启很多服务,这些服务就叫做守护进程。为了增加灵活性,root可以选择系统开启的模式,这些模式叫做运行级别,每一种运行级别以一定的方式配...

亭子happy ⋅ 2012/09/17 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Centos7重置Mysql 8.0.1 root 密码

问题产生背景: 安装完 最新版的 mysql8.0.1后忘记了密码,向重置root密码;找了网上好多资料都不尽相同,根据自己的问题总结如下: 第一步:修改配置文件免密码登录mysql vim /etc/my.cnf 1...

豆花饭烧土豆 ⋅ 今天 ⋅ 0

熊掌号收录比例对于网站原创数据排名的影响[图]

从去年下半年开始,我在写博客了,因为我觉得业余写写博客也还是很不错的,但是从2017年下半年开始,百度已经推出了原创保护功能和熊掌号平台,为此,我也提交了不少以前的老数据,而这些历史...

原创小博客 ⋅ 今天 ⋅ 0

LVM讲解、磁盘故障小案例

LVM LVM就是动态卷管理,可以将多个硬盘和硬盘分区做成一个逻辑卷,并把这个逻辑卷作为一个整体来统一管理,动态对分区进行扩缩空间大小,安全快捷方便管理。 1.新建分区,更改类型为8e 即L...

蛋黄Yolks ⋅ 今天 ⋅ 0

Hadoop Yarn调度器的选择和使用

一、引言 Yarn在Hadoop的生态系统中担任了资源管理和任务调度的角色。在讨论其构造器之前先简单了解一下Yarn的架构。 上图是Yarn的基本架构,其中ResourceManager是整个架构的核心组件,它负...

p柯西 ⋅ 今天 ⋅ 0

uWSGI + Django @ Ubuntu

创建 Django App Project 创建后, 可以看到路径下有一个wsgi.py的问题 uWSGI运行 直接命令行运行 利用如下命令, 可直接访问 uwsgi --http :8080 --wsgi-file dj/wsgi.py 配置文件 & 运行 [u...

袁祾 ⋅ 今天 ⋅ 0

JVM堆的理解

在JVM中,我们经常提到的就是堆了,堆确实很重要,其实,除了堆之外,还有几个重要的模块,看下图: 大 多数情况下,我们并不需要关心JVM的底层,但是如果了解它的话,对于我们系统调优是非常...

不羁之后 ⋅ 昨天 ⋅ 0

推荐:并发情况下:Java HashMap 形成死循环的原因

在淘宝内网里看到同事发了贴说了一个CPU被100%的线上故障,并且这个事发生了很多次,原因是在Java语言在并发情况下使用HashMap造成Race Condition,从而导致死循环。这个事情我4、5年前也经历...

码代码的小司机 ⋅ 昨天 ⋅ 2

聊聊spring cloud gateway的RetryGatewayFilter

序 本文主要研究一下spring cloud gateway的RetryGatewayFilter GatewayAutoConfiguration spring-cloud-gateway-core-2.0.0.RC2-sources.jar!/org/springframework/cloud/gateway/config/G......

go4it ⋅ 昨天 ⋅ 0

创建新用户和授予MySQL中的权限教程

导读 MySQL是一个开源数据库管理软件,可帮助用户存储,组织和以后检索数据。 它有多种选项来授予特定用户在表和数据库中的细微的权限 - 本教程将简要介绍一些选项。 如何创建新用户 在MySQL...

问题终结者 ⋅ 昨天 ⋅ 0

android -------- 颜色的半透明效果配置

最近有朋友问我 Android 背景颜色的半透明效果配置,我网上看资料,总结了一下, 开发中也是常常遇到的,所以来写篇博客 常用的颜色值格式有: RGB ARGB RRGGBB AARRGGBB 这4种 透明度 透明度...

切切歆语 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部