201208 Apr 用python启动一个线程有多少种方法?

开发中遇到的问题,为了满足需求便开始寻找一种合适的控制进程的方法,于是发现了各种方法,然后觉得这块确实比较乱,今天就来理一理并和大家一起分享。

os模块中有大量的进程相关操作,其中可以启动进程的函数有system, fork, exec*, spawn*, popen*,下面详细叙述:

system方法:
函数签名:os.system(command)
说明:同步调用的,即子进程执行完才会返回。返回值为进程结束返回的数字,0表示正常,其他为错误。这个函数把字符串当成令行来执行,就是执行系统命令。可以把它想象成Linux里的shell或者Windows里的cmd来用,但python会直接调用你的command而不是利用shell来间接调用,所以进程树将是python->command。
使用举例:

1
os.system('cat /etc/hosts')
 

fork方法:
函数签名:os.fork()
说明:为Linux/Unix里的特殊方法,无参数,返回子进程pid或者0,子进程中返回0,原进程中返回非0,它将当前进程分裂为两个进程,使用的时候需要用if语句来分支你的进程。
使用举例:

1
2
3
4
5
6
7
pid = os.fork()
if pid: # 这里是原进程,而且你拿到了子进程的pid,继续你的逻辑吧
print 'started a subprocess with pid: %s' % pid
continue your process…
else: # 这里是子进程,你可以启动另一个程序或者随便干点别的什么
os.system('cat /etc/hosts')
print 'subprocess completed'

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)
说明:这个系列的函数将启动一个子进程来代替你当前的进程,它不会返回,直到它执行完你原来的进程也退出了,或者说从它调用的那一刻开始你原来的进程就已经不存在了,被替换成了子进程,但pid不会被换掉。
这几个函数功能基本一样,只有参数的差别。注意看下你将发现规律,l表示子进程参数直接列出来传进去,v表示子进程参数用list传进去,e表示最后一个参数是环境变量,p表示从上下文中的PATH环境变量中寻找可执行文件file,反之需要传入完整路径。
还有一点需要注意的,arg0并不会传给子进程作为参数,而将作为子进程的名字。
使用举例:

1
2
3
os.execv('/bin/echo', ['foo', 'bar'])
执行结果为:
bar

spawn*系列方法
函数签名:
os.spawnl(mode, path, …)
os.spawnle(mode, path, …, env)
os.spawnlp(mode, file, …)
os.spawnlpe(mode, file, …, env)
os.spawnv(mode, path, args)
os.spawnve(mode, path, args, env)
os.spawnvp(mode, file, args)
os.spawnvpe(mode, file, args, env)
说明:启动一个子进程,但子进程执行完之后原进程还在。比exec*多了个mode参数,mode参数可以是os.P_WAIT/os.P_NOWAIT,分别表示是否等待子进程结束,如果等待那么在子进程结束后返回退出值,0为正常退出,非0为错误;如果不等待函数会立即返回,返回值有两种情况,Unix/Linux中返回子进程pid,你可以用这个pid把子进程关闭,不过在windows上有些不同,会返回一个process handler,windows api里可以利用这个handler关闭进程,但python没有实现,所以python拿过来什么也做不了。

popen*系列方法
函数签名:
os.popen(cmd[, mode[, bufsize]])
os.popen2(cmd[, mode[, bufsize]])
os.popen3(cmd[, mode[, bufsize]])
os.popen4(cmd[, mode[, bufsize]])
说明:popen*系列会开启一个子进程,并将子进程输出and/or输入以文件描述符对象返回,其中间细微的差别在于
popen(cmd, ‘w’, buffsize): return child_stdout,
popen(cmd, ‘r’, buffsize): return child_stdin,
popen2: return (child_stdin, child_stdout),
popen3: return (child_stdin, child_stdout, child_stderr),
popen4: return (child_stdin, child_stdout_and_stderr)

subprocess模块是一个专门处理子进程的

Popen类
构造函数签名:Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)
说明:返回子进程对象,之后你可以用这个对象对子进程进行各种操作,功能比较完善。args是一个字符串(可执行文件)或者字符串序列(可执行文件和参数),cwd是给子进程指定程序的当前路径,而不是默认的原进程的当前路径。
使用举例:

1
2
3
p = subprocess.Popen(['python', '-m', 'SimpleHTTPServer'], cwd='/tmp')
time.sleep(3)
p.terminate()

call函数
函数签名:subprocess.call(*popenargs, **kwargs)
说明:同步执行命令,返回完成后的退出结果

check_call函数
函数签名:subprocess.check_call(*popenargs, **kwargs)
说明:同步执行命令,如果命令执行结果码非0则抛出异常CalledProcessError,否则返回0

check_output函数
函数签名:subprocess.check_output(*popenargs, **kwargs)
说明:同步执行命令,将执行结果作为字符串返回,可能会抛出异常,同check_all

其他:
popen2模块里有一些subprocess里类似的函数,但这个模块从2.6开始就已经过时了,在此就不讨论了。

总结起来我想有这么几点说明
1. python真的很乱
2. 区分点:同步/异步,操作系统支持,能否拿到输入输出,


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值