【问题标题】:Designing a perl script with multithreading and data sharing between threads设计具有多线程和线程间数据共享的 perl 脚本
【发布时间】:2010-08-11 23:22:48
【问题描述】:

我正在编写一个 perl 脚本来运行某种管道。我首先读取一个包含一堆参数的 JSON 文件。然后我做一些工作——主要是构建一些稍后需要的数据结构并调用外部程序来生成一些我保留引用的输出文件。

我通常对这些步骤中的每一个都使用一个子例程。每个这样的子例程通常会将一些数据写入其他子例程没有写入的唯一位置(即哈希中的特定键)并读取其他子例程可能已生成的数据。

如果按顺序完成这些步骤可能需要几分钟的时间,但其中大多数可以与我知道如何处理的一些简单的依赖逻辑并行运行(使用线程和队列)。所以我想知道我应该如何实现它以允许在线程之间共享数据。你会建议框架是什么?也许使用一个对象(我将只有一个实例)并将所有共享数据保存在$self 中?也许 一个带有一些“全局”共享变量的简单脚本(无对象)? ...

我显然更喜欢简单、整洁的解决方案。

【问题讨论】:

    标签: multithreading perl


    【解决方案1】:

    阅读threads::shared。默认情况下,您可能知道,perl 变量是不共享的。但是您将shared 属性放在它们上,它们就是。

    my %repository: shared;
    

    那么如果你想同步访问它们,最简单的方法就是

    {   lock( %repository );
        $repository{JSON_dump} = $json_dump;
    }
    # %respository will be unlocked at the end of scope.
    

    但是,您可以使用 Thread::Queue,它应该是无杂乱的,并且也可以这样做:

    $repo_queue->enqueue( JSON_dump => $json_dump );
    

    那么你的消费者线程可以:

    my ( $key, $value ) = $repo_queue->dequeue( 2 );
    $repository{ $key } = $value;
    

    【讨论】:

    【解决方案2】:

    您当然可以在 Perl 中做到这一点,我建议您查看 perldoc threadsperldoc threads::shared,因为这些手册页最能说明在 Perl 中使用线程时遇到的方法和陷阱。

    如果可以的话,我真正建议您使用的是队列管理系统,例如Gearman,它具有各种接口,包括 Perl 模块。这使您可以根据需要创建任意数量的“工作人员”(实际工作的潜艇)并创建一个简单的“客户端”,该客户端将安排适当的任务然后整理结果,而无需使用特定于 hashref 键的技巧任务或类似的事情。

    这种方法也可以更好地扩展,如果您选择的话,您可以在不同的机器上拥有客户和工作人员(甚至是经理)。

    其他队列系统,例如 TheSchwartz,由于缺少 Gearman 提供的反馈/结果,因此不会被指出。总之,以这种方式使用 Gearman 与您描述的线程系统非常相似,只是没有任何基于线程的系统最终可能遭受的麻烦和头痛:必须锁定变量、使用信号量、加入线程。

    【讨论】:

    • 谢谢。我想念的是你建议如何在线程之间共享信息?
    • 大卫,取决于方法:使用线程,使用threads::shared的共享变量。使用 Gearman,您可能希望将关键数据传递给工作线程,而不是共享变量,如“使用此、此和此其他数据执行操作 X”。如果您需要不同的 sub 来处理相同的数据,让它们返回 munged 数据。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-29
    • 1970-01-01
    • 2014-10-17
    • 2011-07-08
    • 2011-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多