Python 巨蟒;can';t酸洗螺纹。锁紧“;在Windows中的多进程下创建线程时出错

Python 巨蟒;can';t酸洗螺纹。锁紧“;在Windows中的多进程下创建线程时出错,python,python-2.7,multiprocessing,python-multithreading,Python,Python 2.7,Multiprocessing,Python Multithreading,我被困在我认为是一个基本的多进程和线程问题上。我已经设置了一个多进程,其中有一个线程。但是,当我在init函数中设置thread类时,会出现以下错误: “TypeError:无法pickle thread.lock对象” 但是,如果线程设置在init函数之外,则不会发生这种情况。有人知道为什么会这样吗?注意,我正在使用Windows 下面是一些代码来说明这个问题。正如下面键入的,它运行良好。但是,如果从dostufinitdef中调用print_hello(),则会发生错误,如果在多进程run(

我被困在我认为是一个基本的多进程和线程问题上。我已经设置了一个多进程,其中有一个线程。但是,当我在init函数中设置thread类时,会出现以下错误:

“TypeError:无法pickle thread.lock对象”

但是,如果线程设置在init函数之外,则不会发生这种情况。有人知道为什么会这样吗?注意,我正在使用Windows

下面是一些代码来说明这个问题。正如下面键入的,它运行良好。但是,如果从dostufinitdef中调用print_hello(),则会发生错误,如果在多进程run()def中调用,则无问题

有人能给我指出正确的方向吗?这样当从init调用它时,它就可以正常运行了?谢谢

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)

看起来没有简单的答案,这似乎是Windows的限制(在我的例子中是Win7、Python3.6);在Windows上,似乎需要先启动进程,然后才能启动所属对象内的工作线程

Unix(CentOS 7、python 2.7.5)上似乎没有这样的限制

作为一个实验,我修改了你的代码如下;此版本检查操作系统并首先启动进程或线程:

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)
。。。并在Windows上获得以下内容,该过程首先从Windows开始:

MyProcess.run()
MyProcess.ident = 14700
DoStuff.start_thread()
MyThread.run() 
MyThread.ident = 14220
MyThread.owner.owner.ident = 14700
。。。在Linux上,首先启动线程:

DoStuff.start_thread()
MyThread.run()
MyThread.ident = 140316342347520
MyThread.owner.owner.ident = None
MyProcess.run()
MyProcess.ident = 4358
如果它是我的代码,我会尝试总是先启动流程,然后在该流程中创建线程;以下版本在两种平台上都适用:

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)