首先把相关的module都列出来:
threading
multiprocessing
subprocess
multiprocessing-with-python-presentation是一个很好的slides对比。
看到了很多例子,由于GIL (global interpreter lock),python thread里是可以用popen的,内核同事说C thread用popen是不对的:threads and fork-think twice before using them
锁
2.5 引入了with statementpep-343阐述了大概原理。大意是 __enter__, __exit__完成了with的工作
这里可以看到,不管有没有异常,__exit__会帮们处理好,所以
- The expression is evaluated and should result in an object called a ``context manager''. The context manager must have __enter__() and __exit__() methods.
- The context manager's __enter__() method is called. The value returned is assigned to VAR. If no
'as VAR'clause is present, the value is simply discarded.- The code in BLOCK is executed.
- If BLOCK raises an exception, the __exit__(type, value, traceback) is called with the exception details, the same values returned by sys.exc_info(). The method's return value controls whether the exception is re-raised: any false value re-raises the exception, and
Truewill result in suppressing it. You'll only rarely want to suppress the exception, because if you do the author of the code containing the 'with' statement will never realize anything went wrong.- If BLOCK didn't raise an exception, the __exit__() method is still called, but type, value, and traceback are all
None.
lock = Threading.Lock() with lock: statements这样的片段是exception安全的,不会因为异常而没有release锁。
Pool:
Pool是一个进程池,可以指定若干个 worker进程来做事情,也分为sync和async的版本,同时可以获得返回值来做一些同步。需要注意的是,在调用pool.close()之后,pool就结束了,如果不小心把pool.close()放在了一个for循环里,或者在apply()之前调用了,比如def func(msg):
for i in xrange(3):
print "func:"+msg
time.sleep(1)
return "hello func %s" % msg
if __name__ == "__main__":
pool = multiprocessing.Pool(processes=2)
result = []
for i in xrange(3):
msg = "hello %d" %(i)
result.append(pool.apply_async(func, [msg]))
pool.close() <--- done.="" es="" for="" in="" obj.get="" obj="" pool.join="" pre="" print="" result:="" tab="" timeout="1)" ub-process="">
会得到一个断言异常:AssertionError: assert self._state == RUN
正确写法是:
def func(msg):
for i in xrange(3):
print "func:"+msg
time.sleep(1)
return "hello func %s" % msg
if __name__ == "__main__":
pool = multiprocessing.Pool(processes=2)
result = []
for i in xrange(3):
msg = "hello %d" %(i)
result.append(pool.apply_async(func, [msg]))
pool.close()
pool.join()
print "Sub-process(es) done."
for obj in result:
print obj.get(timeout=1)
数据访问和共享
--->
没有评论:
发表评论