python - 如何使用多处理在python中创建线程?
问题描述
我试图使用 Process 在 python 中创建线程。
但它一直显示错误。
这是我的代码:
from multiprocessing import Process
import threading
class OneProcess(Process):
def __init__(self):
super().__init__()
self.workers = []
for i in range(5):
worker = OneThread()
self.workers.append(worker)
def run(self):
for worker in self.workers:
worker.start()
for worker in self.workers:
worker.join()
class OneThread(threading.Thread):
def __init__(self):
super().__init__()
def run(self):
print("do somethings")
class Shell():
def __init__(self):
self.first_process = OneProcess()
def start(self):
self.first_process.start()
if __name__ == "__main__":
shell = Shell()
shell.start()
这是错误:
ForkingPickler(file, protocol).dump(obj)
TypeError: can't pickle _thread.lock objects
我猜它只是不能序列化线程对象?那么有没有什么方法可以实现呢?或者使用 Process 创建线程在 python 中是不可用的?
解决方案
我希望@rdas 将他的评论变成一个实际的答案。由于没有任何消息,我将尽我所能回答:
您的代码实际上可以在 Linux 下运行。所以我猜你是在Windows下运行的(我对其他环境了解不够,比如Mac)。线程是在__init__
class 的方法中创建的,该方法OneProcess
在与主进程相同的进程下执行。这在下面的修改代码中得到了证明。但是当self.first_process.start()
执行导致OneProcess.run()
调用的语句时,我们现在正在运行的是子进程,因此必须使用 将OnceProcess
对象的内部状态转移到新的子进程pickle
,这就是发生错误的地方。通过将线程的创建移到run
方法中,没有线程相关的状态要被腌制。
from multiprocessing import Process
import threading
import os
class OneProcess(Process):
def __init__(self):
super().__init__()
print('OneProcess __init__:', os.getpid())
def run(self):
print('OneProcess run:', os.getpid())
self.workers = []
for i in range(5):
worker = OneThread()
self.workers.append(worker)
for worker in self.workers:
worker.start()
for worker in self.workers:
worker.join()
class OneThread(threading.Thread):
def __init__(self):
super().__init__()
def run(self):
print("do somethings")
class Shell():
def __init__(self):
self.first_process = OneProcess()
def start(self):
self.first_process.start()
if __name__ == "__main__":
print('main pid:', os.getpid())
shell = Shell()
shell.start()
印刷:
main pid: 25208
OneProcess __init__: 25208
OneProcess run: 18912
do somethings
do somethings
do somethings
do somethings
do somethings
为什么您的原始代码可以在 Linux 中运行?这与 Linux 支持 OSfork()
调用有关,它在创建新子进程时复制整个进程,因此不必依赖 usingpickle
来传输状态。请参阅当我调用 multiprocessing.Process 时腌制了什么?
推荐阅读
- javascript - 动态视频尺寸
- typescript - 逗号表达式打字稿 4.4.x 输出
- reactjs - 有没有办法在没有花括号的 tsx typescript 代码中进行评论?
- visual-studio - 如何使用 Visual Studio 查找 Blazor 组件(用 razor 编写)的用法?
- kubernetes - Helm 遍历两个子列表
- graalvm - 可以在没有隔离的情况下创建可从 C 调用的 Graal 本机函数吗?
- django - 如何解析文件名(图像)并将它们分配给模型?
- python - 如何在熊猫数据框的行之间应用多个条件创建目标数据框
- console - 谷歌控制台付款后多长时间 25 美元
- python - 如何使用 matplotlib 子图进行多行布局