简体   繁体   English

Python-在Windows中的多进程下创建线程时出现“无法腌制thread.lock”错误

[英]Python - “can't pickle thread.lock” error when creating a thread under a multiprocess in Windows

I'm getting stuck on what I think is a basic multiprocess and threading issue. 我陷入了我认为是基本的多进程和线程问题的困境。 I've got a multiprocess set up, and within this a thread. 我已经建立了一个多进程,并且在其中建立了一个线程。 However, when I set up the thread class within the init function, I get the following error: 但是,当我在init函数中设置线程类时,出现以下错误:

"TypeError: can't pickle thread.lock objects". “ TypeError:无法腌制thread.lock对象”。

However, this does not happen if the thread is set up outside of the init function. 但是,如果线程是在init函数之外设置的,则不会发生这种情况。 Does anyone know why this is happening? 有人知道为什么会这样吗? Note I'm using Windows. 注意我正在使用Windows。

Some code is below to illustrate the issue. 下面的一些代码来说明此问题。 As typed below, it runs fine. 如下键入,它运行正常。 However if print_hello() is called from within the DoStuff init def, then the error occurs, if it's called within the multi-process run() def then it's fine. 但是,如果从DoStuff init def中调用print_hello(),则会发生错误,如果在多进程run()def中调用了它,就可以了。

Can anyone point me in the right direction so it runs fine when called from init ? 谁能指出我正确的方向,以便从init调用时它运行正常? thanks! 谢谢!

import multiprocessing
import threading
import time

class MyProcess(multiprocessing.Process):

    def __init__(self, **kwargs):
        super(MyProcess, self).__init__(**kwargs)
        self.dostuff = DoStuff()

    def run(self):
        print("starting DoStuff")
        # This works fine if the line below is uncommented and __init__ self.print_hello() is commented...
        self.dostuff.print_hello()


class DoStuff(object):
    def __init__(self, **kwargs):
        super(DoStuff, self).__init__(**kwargs)

        # If the following is uncommented, the error occurs...
        #   Note it also occurs if the lines in start_thead are pasted here...
        # self.print_hello()

    def print_hello(self):
        print "hello"
        self.start_thread()

    def start_thread(self):
        self.my_thread_instance = MyThread()
        self.my_thread_instance.start()
        time.sleep(0.1)


class MyThread(threading.Thread):
    def __init__(self):
        super(MyThread, self).__init__()

    def run(self):
        print("Starting MyThread")


if __name__ == '__main__':
    mp_target = MyProcess()       # Also pass the pipe to transfer data
    # mp_target.daemon = True
    mp_target.start()
    time.sleep(0.1)

It looks like there is no simple answer, and it appears to be a restriction of Windows (Win 7, python 3.6 in my case); 似乎没有简单的答案,而且似乎是Windows的限制(在我的情况下是Win 7,python 3.6); on Windows it looks like you need to start the process before you can start the worker thread inside the owned object. 在Windows上,您似乎需要启动进程,然后才能启动拥有的对象内的辅助线程。

There appears to be no such restriction on Unix (CentOS 7, python 2.7.5). 在Unix(CentOS 7,python 2.7.5)上似乎没有这种限制。

As an experiment I modified your code as follows; 作为实验,我修改了您的代码,如下所示; this version checks the OS and starts either the process first, or the thread first: 此版本检查操作系统并首先启动进程,或首先启动线程:

import multiprocessing
import threading
import time
import os

class MyProcess(multiprocessing.Process):

    def __init__(self, **kwargs):
        super(MyProcess, self).__init__(**kwargs)
        self.dostuff = DoStuff(self)

    def run(self):
        print("MyProcess.run()")
        print("MyProcess.ident = " + repr(self.ident))
        if os.name == 'nt':
            self.dostuff.start_thread()

class DoStuff(object):
    def __init__(self, owner, **kwargs):
        super(DoStuff, self).__init__(**kwargs)
        self.owner = owner
        if os.name != 'nt':
            self.start_thread()

    def start_thread(self):
        print("DoStuff.start_thread()")
        self.my_thread_instance = MyThread(self)
        self.my_thread_instance.start()
        time.sleep(0.1)

class MyThread(threading.Thread):
    def __init__(self, owner):
        super(MyThread, self).__init__()
        self.owner = owner

    def run(self):
        print("MyThread.run()")
        print("MyThread.ident = " + repr(self.ident))
        print("MyThread.owner.owner.ident = " + repr(self.owner.owner.ident))

if __name__ == '__main__':
    mp_target = MyProcess()       # Also pass the pipe to transfer data
    mp_target.daemon = True
    mp_target.start()
    time.sleep(0.1)

... and got the following on Windows, where the process starts first: ...并在Windows上获得了以下内容,该过程首先开始:

MyProcess.run()
MyProcess.ident = 14700
DoStuff.start_thread()
MyThread.run() 
MyThread.ident = 14220
MyThread.owner.owner.ident = 14700

... and the following on Linux, where the thread is started first: ...以及在首先启动线程的Linux上的以下版本:

DoStuff.start_thread()
MyThread.run()
MyThread.ident = 140316342347520
MyThread.owner.owner.ident = None
MyProcess.run()
MyProcess.ident = 4358

If it were my code I'd be tempted to always start the process first, then create the thread within that process; 如果是我的代码,我很想总是先启动该过程,然后在该过程中创建线程。 the following version works fine for me across both platforms: 以下版本在两个平台上都适合我:

import multiprocessing
import threading
import time

class MyProcess(multiprocessing.Process):

    def __init__(self, **kwargs):
        super(MyProcess, self).__init__(**kwargs)
        self.dostuff = DoStuff()

    def run(self):
        print("MyProcess.run()")
        self.dostuff.start_thread()

class DoStuff(object):
    def __init__(self, **kwargs):
        super(DoStuff, self).__init__(**kwargs)

    def start_thread(self):
        self.my_thread_instance = MyThread()
        self.my_thread_instance.start()
        time.sleep(0.1)

class MyThread(threading.Thread):
    def __init__(self):
        super(MyThread, self).__init__()

    def run(self):
        print("MyThread.run()")

if __name__ == '__main__':
    mp_target = MyProcess()       # Also pass the pipe to transfer data
    mp_target.daemon = True
    mp_target.start()
    time.sleep(0.1)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 不能泡菜 <type 'thread.lock'> 使用python multiprocess.pool.map_async()时 - Can't pickle <type 'thread.lock'> when using python multiprocess.pool.map_async() Python 3.x多进程TypeError:无法腌制_thread.lock对象 - Python 3.x multiprocess TypeError: can't pickle _thread.lock objects Python多处理,无法腌制thread.lock(pymongo) - Python multiprocessing, can't pickle thread.lock (pymongo) Joblib错误:TypeError:无法腌制_thread.lock对象 - Joblib error: TypeError: can't pickle _thread.lock objects 多处理,Python3,Windows:TypeError:无法腌制 _thread.lock 对象 - Multiprocessing, Python3, Windows: TypeError: can't pickle _thread.lock objects 在将Queue传递给子进程中的线程时,如何解决“ TypeError:无法腌制_thread.lock对象” - How to fix 'TypeError: can't pickle _thread.lock objects' when passing a Queue to a thread in a child process 收到TypeError:无法腌制_thread.lock对象 - Getting TypeError: can't pickle _thread.lock objects Cassandra多处理无法腌制_thread.lock对象 - Cassandra multiprocessing can't pickle _thread.lock objects 使用 Queue() 进行多处理:TypeError: can't pickle _thread.lock objects - Multiprocessing with Queue(): TypeError: can't pickle _thread.lock objects Keras:TypeError:无法使用KerasClassifier来pickle _thread.lock对象 - Keras: TypeError: can't pickle _thread.lock objects with KerasClassifier
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM