幸运的是,自 2.6 版本起,Python 包括了一个名为 “多进程(multiprocessing)” 的模块来帮助处理进程。该进程模块的 API 与线程 API 的工作方式有些相似点,但是也存在一些需要特别注意的不同之处。主要区别之一就是进程拥有的一些微妙的底层行为,这是高级 API 永远无法完全抽象出来的。
fork 简介
进程和线程在并发性的工作原理方面存在一些明显的差异。在进程执行 fork 时,操作系统将创建具有新进程 ID 的新的子进程,复制父进程的状态(内存、环境变量等)。首先,在我们实际使用进程模块之前,先看一下 Python 中的一个非常基本的 fork 操作。
#!/usr/bin/env python from multiprocessing import Process import os import time
def sleeper(name, seconds): print 'starting child process with id: ', os.getpid() print 'parent process:', os.getppid() print 'sleeping for %s ' % seconds time.sleep(seconds) print "Done sleeping"
if name == 'main': print "in parent process (id %s)" % os.getpid() p = Process(target=sleeper, args=('bob', 5)) p.start() print "in parent process after child process start" print "parent process about to join child process" p.join() print "in parent process after child process join" print "parent process exiting with id ", os.getpid() print "The parent's parent process:", os.getppid()
Show moreShow more icon
如果查看输出,将会看到下面的内容:
1 2 3 4 5 6 7 8 9 10 11
mac% python simple.py in parent process (id 5245) in parent process after child process start parent process about to join child process starting child process with id: 5246 parent process: 5245 sleeping for 5 Done sleeping in parent process after child process join parent process exiting with id 5245 The parent's parent process: 5231
#!/usr/bin/env python2.6 """ This is a multiprocessing wrapper for Net‑SNMP. This makes a synchronous API asynchronous by combining it with Python2.6 """
import netsnmp from multiprocessing import Process, Queue, currentprocess
class SnmpSession(): """A SNMP Session""" def init(self, oid = "sysDescr", Version = 2, DestHost = "localhost", Community = "public", Verbose = True, ): self.oid = oid self.Version = Version self.DestHost = DestHost self.Community = Community self.Verbose = Verbose self.var = netsnmp.Varbind(oid, 0) self.hostrec = HostRecord() self.hostrec.hostname = self.DestHost
def query(self): """Creates SNMP query
Fills out a Host Object and returns result """ try: result = netsnmp.snmpget(self.var, Version = self.Version, DestHost = self.DestHost, Community = self.Community) self.hostrec.query = result except Exception, err: if self.Verbose: print err self.hostrec.query = None finally: return self.hostrec
def makequery(host): """This does the actual snmp query
This is a bit fancy as it accepts both instances of SnmpSession and host/ip addresses. This allows a user to customize mass queries with subsets of different hostnames and community strings """ if isinstance(host,SnmpSession): return host.query() else: s = SnmpSession(DestHost=host) return s.query()
#Function run by worker processes def worker(input, output): for func in iter(input.get, 'STOP'): result = makequery(func) output.put(result)
如果在对 Net-SNMP 进行监听的 OS X 机器上运行代码,那么将会得到如下所示的非阻塞输出:
1 2 3 4 5 6 7 8 9
mac% time python multisnmp.py Unordered results: ('Darwin mac.local 9.6.0 Darwin Kernel Version 9.6.0: Mon Nov 24 17:37:00 PST 2008; root:xnu‑1228.9.59~1/RELEASE_I386 i386',) ('Darwin mac.local 9.6.0 Darwin Kernel Version 9.6.0: Mon Nov 24 17:37:00 PST 2008; root:xnu‑1228.9.59~1/RELEASE_I386 i386',) Stopping Process #0 Stopping Process #1 python multisnmp.py 0.18s user 0.08s system 107% cpu 0.236 total
Show moreShow more icon
配置 OS X 的 SNMPD
如果希望配置 OS X 的 SNMP Daemon 以针对本文进行测试,那么需要执行下面的操作。首先,在 shell 中使用三个命令重写配置文件:
Reprint policy:
All articles in this blog are used except for special statements
CC BY 4.0
reprint policy. If reproduced, please indicate source
John Doe
!