Python 2.7使用multiprocessing报错PicklingError: Can't pickle : attribute lookup __builtin__.instancemethod failed

Python 2.7中使用下面代码的时候

import multiprocessing
 
class examplePool:

    def __init__(self):
        self.pool = multiprocessing.Pool()

    def run(self,args):
        print args

    def runProcessPool(self):
        self.pool.apply(self.run,(60,))
        self.pool.close()
        self.pool.join()

if __name__ == '__main__':
    pool = examplePool()
    pool.runProcessPool()

会报告如下错误:

Traceback (most recent call last):
  File "text.py", line 18, in <module>
    pool.runProcessPool()	
  File "text.py", line 12, in runProcessPool
    self.pool.apply(self.run,(60,))
  File "/usr/lib/python2.7/multiprocessing/pool.py", line 244, in apply
    return self.apply_async(func, args, kwds).get()
  File "/usr/lib/python2.7/multiprocessing/pool.py", line 567, in get
    raise self._value
cPickle.PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup __builtin__.instancemethod failed

这种错误发生的原因是Python 2.7版本中的multiprocessing模块的进程池部分存在BUG,无法正常处理这种写法的代码,据说在Python 3.4版本之后解决了此问题。

目前测试来看,不用Python 2.7中的进程池,而是自己创建进程,自己管理进程的方式,可以比较简单的解决此类问题。

比如代码修改成如下样子,即可正常运行

import multiprocessing
 
class exampleProcess:

    def __init__(self):
        self.process = multiprocessing.Process(target=self.run,args=(60,))

    def run(self,args):
        print args

    def runProcess(self):
        self.process.start()
        self.process.join()

if __name__ == '__main__':
    process = exampleProcess()
    process.runProcess()

至于多进程的管理,则只需要使用

from multiprocessing import Process, Queue

引入multiprocessing模块的Queue,实现一个简单的生产者,消费者模型即可。

参考链接


python multiprocessing遇到Can’t pickle instancemethod问题

WARNING:libav.swscaler:Warning: data is not aligned! This can lead to a speedloss

Python中使用libav视频解码的时候,如果需要更改最后输出的视频的宽高,比如如下代码:

width = 240
container = av.open(url)
video_stream = next(s for s in container.streams if s.type == 'video')
for packet in container.demux(video_stream):
   for frame in packet.decode():
        if frame is None:
            break
        frame = frame.reformat(width,height)
        img = frame.to_image()

可能会收到一条警告信息

WARNING:libav.swscaler:Warning: data is not aligned! This can lead to a speedloss

导致警告的原因是swscaler的缩放的目标尺寸不合适,它预期的大小是16的倍数,这个倍数可以保证swscaler以最高效的方式进行图片的缩放处理。

解决警告的方式就是保证宽高都是16的倍数即可。

参考链接


[swscaler] Warning: data is not aligned! This can lead to a speedloss 的解决方法【FFmpeg】

Ubuntu 16.04 LTS根据进程名结束所有同名进程

最近在调试脚本时,偶尔会由于脚本错误,出现一批的进程没有结束的情况. 手工结束进程,太浪费时间,因此找到一个可以批量结束同名进程的脚本命令,如下:

$ ps -ef | grep '进程名' | grep -v grep | awk '{print $2}' | xargs kill -9

参考链接


Linux Shell脚本实现根据进程名杀死进程