perl如何模拟线程行为

时间:2013-01-16 10:15:29

标签: perl unit-testing

我想在perl中为子程序编写单元测试。子例程使用多个线程来完成其任务。因此,它首先创建一些线程然后等待它们加入。

问题是我们的单元测试运行在无法运行多线程测试的服务器上,所以我需要以某种方式模拟线程行为。基本上我想覆盖线程创建和连接函数,使其不再是线程。任何指针如何做到这一点并测试代码?

编辑:由于以下原因,服务器无法运行线程代码:

  

Devel :: Cover尚未使用线程

1 个答案:

答案 0 :(得分:5)

更新:此答案无法解决编辑问题中描述的OP问题,但对某人可能有用。

Perl线程是解释器仿真,而不是操作系统功能。所以,他们应该在任何平台上工作。如果您的测试服务器不支持线程,则可能是出于以下原因之一:

  1. 您的Perl版本非常旧。
  2. Perl编译时没有线程支持。
  3. 您的测试框架并未考虑使用线程代码。
  4. 通过更新您的环境可以轻松纠正前两个问题。但是,我怀疑你的是第三个问题。

    我认为你不应该通过模拟线程行为来解决这个问题。这会将原始代码更改为有效测试。无论如何,这将是一项重要的工作,那么为什么不直接努力使线程测试工作呢?

    确切的问题取决于你的代码,但问题可能是你的子程序启动一个线程然后返回,线程仍在运行。然后你的测试框架反复运行sub,累积了一大堆并发线程。

    在这种情况下,您需要的只是一个包装子,它调用您正在测试的子,然后阻塞直到线程完成。这应该很简单。查看threads->list()以了解如何检测正在运行的线程。只需要一个循环,等待有问题的线程在退出包装子之前不再运行。

    这是一个演示包装器子的简单完整示例:

    #!usr/bin/perl
    use strict;
    use warnings;
    use threads;
    
    sub sub_to_test {
    
        threads->create(sub { sleep 5; print("Thread done\n"); threads->detach() });
        return "Sub done\n";
    }
    
    sub wrapper {
        #Get a count of the running threads.
        my $original_running_threads = threads->list(threads::running);
    
        my @results = sub_to_test(@_);
    
        #block until the number of running threads is the same as when we started.
        sleep 1 while (threads->list(threads::running) > $original_running_threads);
    
        return @results;
    }
    
    print wrapper;