Python 多处理与多线程相结合

2024-04-01

我不确定我想做的是否是有效的做法,但事情是这样的: 我需要我的程序高度并行化,所以我想我可以创建 2-3 个进程,每个进程可以有 2-3 个线程。

1)这可能吗? 2)这有什么意义吗? 3)这是我的代码,但当我尝试加入进程时它会挂起。

PQ = multiprocessing.Queue()

[...]

def node(self, files, PQ):

        l1, l2 = self.splitList(files)
        p1 = multiprocessing.Process(target=self.filePro, args=(l1,PQ,))
        p2 = multiprocessing.Process(target=self.filePro, args=(l2,PQ,))
        p1.daemon = True
        p2.daemon = True
        p1.start()
        p2.start()

        p1.join() # HANGS HERE
        p2.join()
        while 1:
            if PQ.empty():
                break
            else:
                print(PQ.get())
        PQ.join()

    def filePro(self,lst,PQ):
        TQ = queue.Queue()
        l1, l2 = self.splitList(lst)
        t1 = threading.Thread(target=self.fileThr, args=('a',l1,TQ,))
        t2 = threading.Thread(target=self.fileThr, args=('b',l2,TQ,))
        t1.daemon = True
        t2.daemon = True
        t1.start()
        t2.start()

        t1.join()
        t2.join()
        while 1:
            if TQ.empty():
                break
            else:
                PQ.put(TQ.get())
                TQ.task_done()
        TQ.join()

def fileThr(self,id,lst,TQ):
        while lst:
            tmp_path = lst.pop()
            if (not tmp_path[1]):
                continue
            for item in tmp_path[1]:
                TQ.put(1)
        TQ.join()

1)这可能吗?

Yes.


2)这有什么意义吗?

是的。但通常不是您要寻找的点。

首先,几乎每个现代操作系统都使用“平面”调度程序;分散在 3 个程序中的 8 个线程或分散在 8 个程序中的 8 个线程之间没有区别。*

* Some programs can get a significant benefit by carefully using intraprocess-only locks or other synchronization primitives in some places where you know you're only sharing with threads from the same program—and, of course, by avoiding shared memory in those places—but you're not going to get that benefit by spreading your jobs across threads and your threads across processes evenly.

其次,即使您使用旧的 SunOS,在默认的 CPython 解释器中,全局解释器锁 (GIL) 也会确保一次只有一个线程可以运行 Python 代码。如果您花时间从显式释放 GIL 的 C 扩展库(如某些 NumPy 函数)运行代码,线程可以提供帮助,但否则,它们最终都会被序列化。

线程和进程一起使用的主要情况是同时处理 CPU 密集型和 I/O 密集型工作。在这种情况下,通常一个人正在喂另一个人。如果 I/O 为 CPU 提供数据,请在主进程中使用单个线程池来处理 I/O,然后使用工作进程池来对结果执行 CPU 工作。如果是相反的方式,请使用工作进程池来执行 CPU 工作,然后让每个工作进程使用线程池来执行 I/O。


3)这是我的代码,但当我尝试加入进程时它会挂起。

当你不给出一个信息时,调试代码是非常困难的最小的、完整的、可验证的示例 https://stackoverflow.com/help/mcve.

然而,我可以看到一个明显的问题。

你正在尝试使用TQ作为生产者-消费者队列,t1 and t2作为生产者和filePro父母作为消费者。您的消费者不打电话TQ.task_done()直到之后t1.join() and t2.join()返回,直到这些线程完成后才会发生。但那些制作人不会完成,因为他们在等你打电话TQ.task_done()。所以,你陷入了僵局。

而且,因为每个子进程的主线程都死锁,它们永远不会完成,所以p1.join()将永远阻塞。

如果您确实希望主线程在执行任何工作之前等待其他线程完成,则不需要生产者-消费者习惯用法;让孩子们做完他们的事然后退出而不打电话TQ.join(),并且不用担心TQ.task_done()在父级中。 (请注意,您已经正确执行了此操作PQ.)

另一方面,如果您希望它们并行工作,请不要尝试join子线程直到你完成循环。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python 多处理与多线程相结合 的相关文章

随机推荐

  • CURLOPT_FOLLOWLOCATION 无法激活[重复]

    这个问题在这里已经有答案了 所以我在多个服务器上不断收到这个恼人的错误 它是一个警告 所以我会忽略它 但我需要该功能 警告 curl setopt function curl setopt 当启用 safe mode 或在第 56 行 ho
  • 为android中的应用程序制作小部件

    我已经在android中做了一个应用程序 现在我的要求是我想为此应用程序制作一个小部件 我已经做了一个Widget Demo 但我不知道如何通过小部件图标启动我的应用程序 请给我一个方法来做到这一点 任何帮助将不胜感激 主要类别 publi
  • 将 CLR 类型转换为 void* 并返回

    例如 如何正确转换 CLR 类型Foo to void 过一段时间再回来 场景是 我在 DLL 中有一些非托管代码 可以总结为 class Handler void obj void call void obj int detail voi
  • 使用 JavaScript 获取给定月份的给定工作日

    我试图获取某个日期所在月份的第 n 个工作日 例如 第二个星期日 例如 如果日期是 2015 年 8 月 24 日 我想这样做 nthDayOfMonth 0 2 new Date 2015 7 24 并获取 2015 年 8 月 9 日
  • iPhone REST 客户端 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • AlertDialog 中的 Android EditText 似乎太宽

    下图中的 EditText 似乎太宽了 我假设我以某种方式滥用了 SDK 除非确信 否则我不会寻找一种方法来指定边缘 填充像素的数量EditText 这个看起来比较合适 这是我的代码 创建第一个 创建标签 对话框 final Dao
  • websphere - CWWKE0054E 错误无法打开文件

    我正在尝试从命令行运行 websphere liberty profile 服务器 我正在按照此处所述的步骤进行操作 https developer ibm com wasdev downloads liberty profile usin
  • netstandard20 中的 System.Data.Linq

    我有一个引用 Net 4 6 项目的 netstandard20 项目 除了我调用 Net 4 6 项目中的任何功能之外 所有项目都会编译和运行 我收到以下错误 FileNotFoundException 无法加载文件或程序集 System
  • 自动运行 CSS 更改

    我知道有解决方案可以解决这个问题 但我想在我的 自己的 你必须知道你的限制 Hello stackoverflow 路径上完成这项工作 所以我想要一种轮播 只要用户不将鼠标悬停在 ul 区域上 整个 ul 元素就会在每个设定的时间间隔内获得
  • group by 和 group concat ,不使用main pk优化mysql查询

    我的例子是 MYSQL 版本是 5 6 34 日志 Problem摘要以下查询需要40秒 订单商品 table has 758423 records And PAYMENT table has 177272 records And 提交条目
  • LINQ to Entities 不支持 LINQ 表达式节点类型“ArrayIndex”

    public List
  • 选项卡更改时刷新/重新加载 MUI WPF 页面

    我正在使用 WPF 的 Modern UI 开发桌面应用程序 当我转到新标签页时 我尝试刷新我的标签页 但我做不到 当我使用选项卡控制器转到另一个页面时 我想刷新我的 MUI WPF 选项卡页面 谁能帮我 我不太清楚你的意思到底是什么 但是
  • 将字符串中保存的数字中的每个数字转换为 int 数组

    我正在 DFA 上编写这个项目 我想将保存为字符串的整数的每个数字保存并转换为 int 数组 这是负责此操作的函数的代码 int l final states size int temp final temp final new int l
  • 覆盖 Rails 中的 MIME 类型

    我想将 Rails 中的 JSON MIME 类型 application json 覆盖为 text x json 我尝试在 mime types rb 中再次注册 MIME 类型 但这不起作用 有什么建议么 Thanks 这应该可以工作
  • c2512 错误:没有合适的默认构造函数可用

    即使我声明了构造函数 我也遇到了 c2512 错误 我的代码是这样的 在我的 first h 文件中 我将其声明为 class myClass public tmpM cv Mat model 然后在我的 first cpp 中我做了 in
  • 从 Word OLE 应用程序对象获取应用程序标题

    有没有办法从 Word Application OLE 对象获取窗口标题 我想用它来尝试使用窗口FindWindow 我正在创建一个 OLE 对象并添加一个现有文档 如下所示 App CreateOLEObject Word Applica
  • Java - 如何限制特定方法的方法调用

    我有一个特殊的要求 我需要确保只允许一个类中的特定方法调用第二个类中的公共 非静态 方法 不能使用继承 一种选择是使用 StackTrace 如下所示 A类 java package org rnd stack public class C
  • .ToTitleCase 不适用于所有大写字符串

    Public Function TitleCase ByVal strIn As String Dim result As String Dim culture As New CultureInfo en False Dim tInfo A
  • 将 std::wstring 从 Visual Studio 移植到 mingw gcc

    我正在将一些代码从 Visual Studio 移植到 mingw gcc 我看到了这个声明 if mnode GetTag T val return true 这是 GetTag 方法的定义 const std wstring GetTa
  • Python 多处理与多线程相结合

    我不确定我想做的是否是有效的做法 但事情是这样的 我需要我的程序高度并行化 所以我想我可以创建 2 3 个进程 每个进程可以有 2 3 个线程 1 这可能吗 2 这有什么意义吗 3 这是我的代码 但当我尝试加入进程时它会挂起 PQ mult