python os模块进程函数

系统进程<a id="sec-1" name="sec-1"></a>

今天在看《Beginning Linux Programming》中的进程相关部分,讲到Linux几个进程相关的系统函数: system, exec, fork, wait. Python的 os 模块实现了对应的函数封装了这些系统调用: os.system, os.exec, os.fork, os.wait.

1. os.system(command)
# 在一个程序内部启动另一个程序,从而创建一个新进程
# os.system 在一个shell中执行command命令,这是一个对C函数system()的python实现,具有相同的限制条件。在Unix系统中,返回值是命令执行后的退出状态值。由于POSIX没有为C函数system()的返回值指定明确的含义,所以os.system()的返回值依# 赖具体的系统。在Windowns中,返回值由系统环境变量决定: COMSPEC, 此环境变量依据不同系统版本不同
# 因为os.system的局限性,官方文档建议用 subprocess模块的功能来代替此函数

2. os.exec系列
os.execl(path, arg0, arg1, ...)
os.execle(path, arg0, arg1, ..., env)
os.execlp(file, arg0, arg1, ...)
os.execlpe(file, arg0, arg1, ..., env)
os.execv(path, args)
os.execve(path, args, env)
os.execvp(file, args)
os.execvpe(file, args, env)
# 这些函数都执行一个新的程序,然后用新的程序替换当前子进程的进程空间,而该子进程从新程序的main函数开始执行。在Unix下,该新程序的进程id是原来被替换的子进程的进程id。原来的程序不再运行。在原来子进程中打开的所有描述符默认都是可用的,不会被关闭。
# execv*系列的函数表示其接受的参数是以一个list或者是一个tuple表示的参数表
# execl*系列的函数表示其接受的参数是一个个独立的参数传递进去的。
# exec*p*系列函数表示在执行参数传递过去的命令时使用PATH环境变量来查找命令
# exec*e系列函数表示在执行命令的时候读取该参数指定的环境变量作为默认的环境配置,最后的env参数必须是一个mapping对象,可以是一个dict类型的对象。

3. os.fork (只在Unix有效)
# 要想让进程同时执行多个函数,可以使用线程或者从原程序中创建一个完全分离的进程。可以通过fork创建一个新进程。这个调用复制当前进程,在系统的进程表上创建一个新表项,新表项中的许多属性与当前进程相同。但新进程有自己的数据空间、环境和文件描述符
# os.fork出一个子进程,在子进程中返回0,在父进程中返回子进程ID,如果发生错误,则抛出OSError异常
# 注意:在一些平台下如FreeBSD,Cygwin和OS/2 EMX系统中使用该函数会有问题。

4. os.wait (只在Unix有效)
# 当fork启动一个子进程时,子进程有了自己的生命周期并独立运行,有时候希望知道一个子进程何时结束,这时可以通过wait函数让父进程等待子进程运行结束
# os.wait 等待任何一个子进程结束,返回一个tuple,包括子进程的进程ID和退出状态信息:一个16位的数字,低8位是杀死该子进程的信号编号,而高8位是退出状态(如果信号编号是0),其中低8位的最高位如果被置位,则表示产生了一个core文件。
# 相关的的有os.waitpid(pid, options)

举例<a id="sec-2" name="sec-2"></a>

os.fork<a id="sec-2-1" name="sec-2-1"></a>

#!/usr/bin/python
#coding=utf-8
import os

def child():
    print('hello from child', os.getpid(), os.getppid())    #前者获取进程id, 或者获取父进程id
    os._exit(0)     # 退出进程, 通常只用在fork() 产生的子进程中

def parent():
    pid = os.fork()   # 返回的pid在父进程中为子进程PID,在资进程中为0, 所以下面根据pid判断是哪个进程
    if pid == 0:
        child()
        print 'fork child process error!'    #如果打印该字符串,说明调用child()出错
    else:
        print('hello from parent', os.getpid(), pid)

parent()

我电脑上运行结果如下:

-> python test.py

('hello from parent', 1952, 1953)
('hello from child', 1953, 1952)

os.exec 和 os.system<a id="sec-2-2" name="sec-2-2"></a>

os.execlp的测试代码如下:

#!/usr/bin/python
#coding=utf-8
import os

def main():
    print "Running ps with execlp"
    os.execlp("ps", 'ps', 'ax')
    print "Done."

main()

运行结果:

-> python test4.py
Running ps with execlp
  PID   TT  STAT      TIME COMMAND
    1   ??  Ss     0:12.43 /sbin/launchd
   42   ??  Ss     0:03.05 /usr/libexec/UserEventAgent (System)
   43   ??  Us     0:05.24 /usr/sbin/syslogd
...
  481 s000  S+     0:00.14 -zsh
 1803 s001  Ss+    0:00.49 /usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versio
 1806 s002  Ss     0:00.10 /bin/zsh -i
 2070 s002  R+     0:00.02 ps ax

os.system的测试代码如下:

#!/usr/bin/python
#coding=utf-8
import os

def main():
    print "Running ps with execlp"
    os.system("ps ax")
    print "Done."

main()

运行结果如下:

-> python test4.py
Running ps with execlp
  PID   TT  STAT      TIME COMMAND
    1   ??  Ss     0:12.71 /sbin/launchd
   42   ??  Ss     0:03.11 /usr/libexec/UserEventAgent (System)
...
  481 s000  S+     0:00.14 -zsh
 1803 s001  Ss+    0:00.50 /usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versio
 1806 s002  Ss     0:00.10 /bin/zsh -i
 2113 s002  S+     0:00.02 /usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versio
 2114 s002  R+     0:00.00 ps ax
Done.

以上两个例子对比可以看到 exec系列 的调用使得原进程接下的代码都不会运行。

os.wait<a id="sec-2-3" name="sec-2-3"></a>

#! /usr/bin/python
#coding=utf-8

import os
import sys

def child_process():
    '''child process'''
    print 'child process is running'
    sys.exit(0)                 # 常用的退出进程

def parent_process():
    '''parent process'''
    print 'parent process is running'
    print 'waiting for child process'
    exit_stat = os.wait()     # 返回值是一个pid 和退出状态的元组
    print "waited child process's PID = %d" % (exit_stat[0])
    sys.exit(0)

def main():
    '''main function'''
    try:
        pid = os.fork()
        if pid > 0:
            '''parent process'''
            parent_process()
        else:
            child_process()
    except OSError, e:
        print os.strerror(e.errno)


main()

运行结果:

-> python test4.py
parent process is running
waiting for child process
child process is running
waited child process's PID = 2152

总结<a id="sec-3" name="sec-3"></a>

本文简单介绍了系统进程相关的 os.system, os.exec, os.fork, os.wait 系统调用。相关的其它调用如:
os.kill, os.ncie, os.popen, os.spawn系列 可以参照官方文档。另外实际上python多进程编程更加推荐 multiprocessing 模块提供的相关功能,将在以后的文章中探究。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容

  • Linux 进程管理与程序开发 进程是Linux事务管理的基本单元,所有的进程均拥有自己独立的处理环境和系统资源,...
    JamesPeng阅读 2,405评论 1 14
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,100评论 18 139
  • 又来到了一个老生常谈的问题,应用层软件开发的程序员要不要了解和深入学习操作系统呢? 今天就这个问题开始,来谈谈操...
    tangsl阅读 4,004评论 0 23
  • 范七2Jae Chapter37.逆光歌友会(二) 到歌友会开始前一分钟的时候,频道里的人数已然直逼五位数,闻香识...
    亦木辛阅读 194评论 0 2