Python ProcessPoolExecutor logging Not pickle able

 近几天用Python写一个并发的计算引擎,遇到一些问题,经过一段时间的调试终于解决了。特记录如下,以供参考。

 python3.5, loggiing的问题。


1. 简单的代码:

import logging
import concurrent.futures
import pandas as pd
import numpy as np


class Work: def __init__( self , number): self.number = number self.logger = logging.getLogger(__name__) self.arr = np.zeros( 5) self.date = pd.datetime.now() self.logger.setLevel(logging.DEBUG) def do_work( self): self.logger.info( "I am working number %s" % str( self.number)) cal_data = my_problem() df = pd.DataFrame({ "Number": cal_data}) return df , self.arr , self.date
def test_process():
    with concurrent.futures.ProcessPoolExecutor(max_workers=5) as executors:
        print("Process pool executor started")
        future_list = []
        for i in range(5):
            work = Work(i)
            pickled = pickle.dumps(work)
            print(pickled)
            future_list.append(executors.submit(call_do_work, work))
        for futures in concurrent.futures.as_completed(future_list):
            print(str(futures.result()))

if __name__ == "__main__":
     logging.basicConfig(level=logging.DEBUG)

  test_process() 

在Linux上,会报出以下错误:

Traceback (most recent call last):
  File "./mutli_process_test.py", line 119, in
    test_process()
  File "./mutli_process_test.py", line 110, in test_process
    pickled = pickle.dumps(work)
TypeError: cannot serialize '_io.TextIOWrapper' object


2 两种解决方案:

  • 最简单的解决方案

          去掉下面的行       

 
  
 
  
 
  
     logging.basicConfig(level=logging.DEBUG)

  •  给类增加

def __getstate__(self):
    odict = self.__dict__.copy()
    del odict['logger']
    return odict

def __setstate__(self, state):
    self.__dict__.update(state)
    self.logger = logging.getLogger(__name__)
    self.logger.setLevel(logging.INFO)
      


3 总结:

    以上简单的问题,如果没有遇到,不太容易找到现成的解决方案。网上的很多有关这个的讨论,也不是很直接。

    如果有人遇到相同的问题,可以很快的找到思路和解决方案。





你可能感兴趣的:(python)