TypeError: can't pickle _thread.lock objects

前端 未结 3 1584
没有蜡笔的小新
没有蜡笔的小新 2020-12-02 20:15

Trying to run two different functions at the same time with shared queue and get an error...how can I run two functions at the same time with a shared queue? This is Python

3条回答
  •  爱一瞬间的悲伤
    2020-12-02 20:23

    I had the same problem with Pool() in Python 3.6.3.

    Error received: TypeError: can't pickle _thread.RLock objects

    Let's say we want to add some number num_to_add to each element of some list num_list in parallel. The code is schematically like this:

    class DataGenerator:
        def __init__(self, num_list, num_to_add)
            self.num_list = num_list # e.g. [4,2,5,7]
            self.num_to_add = num_to_add # e.g. 1 
    
            self.run()
    
        def run(self):
            new_num_list = Manager().list()
    
            pool = Pool(processes=50)
            results = [pool.apply_async(run_parallel, (num, new_num_list)) 
                          for num in num_list]
            roots = [r.get() for r in results]
            pool.close()
            pool.terminate()
            pool.join()
    
        def run_parallel(self, num, shared_new_num_list):
            new_num = num + self.num_to_add # uses class parameter
            shared_new_num_list.append(new_num)
    

    The problem here is that self in function run_parallel() can't be pickled as it is a class instance. Moving this parallelized function run_parallel() out of the class helped. But it's not the best solution as this function probably needs to use class parameters like self.num_to_add and then you have to pass it as an argument.

    Solution:

    def run_parallel(num, shared_new_num_list, to_add): # to_add is passed as an argument
        new_num = num + to_add
        shared_new_num_list.append(new_num)
    
    class DataGenerator:
        def __init__(self, num_list, num_to_add)
            self.num_list = num_list # e.g. [4,2,5,7]
            self.num_to_add = num_to_add # e.g. 1
    
            self.run()
    
        def run(self):
            new_num_list = Manager().list()
    
            pool = Pool(processes=50)
            results = [pool.apply_async(run_parallel, (num, new_num_list, self.num_to_add)) # num_to_add is passed as an argument
                          for num in num_list]
            roots = [r.get() for r in results]
            pool.close()
            pool.terminate()
            pool.join()
    

    Other suggestions above didn't help me.

提交回复
热议问题