Perl线程不会挂起/恢复

时间:2016-07-22 15:23:07

标签: multithreading perl

我正在使用Thread::Suspend从远程模块启动线程。某些$subrotine次呼叫的持续时间超过30秒。

my $thr = threads->create(sub {
    capture(EXIT_ANY, $^X, $pathToModule, $subroutine, %arguments)
});
return $thr->tid();

我的问题是我无法暂停/恢复已创建的帖子。以下是执行暂停线程的代码:

use IPC::System::Simple qw (capture $EXITVAL EXIT_ANY);
use threads;
use Thread::Suspend; 
use Try::Tiny; 

sub suspendThread {
    my $msg;
    my $threadNumber = shift;

    foreach (threads->list()) {
        if ($_->tid() == $threadNumber) {
            if ($_->is_suspended() == 0) {
                try {
                    # here the execution of the thread is not paused
                    threads->suspend($_);
                } catch {
                    print "error: " . $! . "\n";
                };

                $msg = "Process $threadNumber paused";
            } else {
                $msg = "Process $threadNumber has to be resumed\n";
            }   
        }
    }

    return $msg;
}

这是我动态加载的模块中的代码:

sub run {
    no strict 'refs';
    my $funcRef = shift;
    my %paramsRef = @_;
    print &$funcRef(%paramsRef);
}

run(@ARGV);

我想问题是传递给踏板构造函数的sub调用capture(来自IPC::System::Simple模块)。我还尝试使用my $thr = threads->create(capture(EXIT_ANY, $^X, $pathToModule, $subroutine, %arguments));创建线程。如何解决它。

1 个答案:

答案 0 :(得分:3)

这些是您拥有的主题:

Parent process                  Process launched by capture
+---------------------+         +---------------------+
|                     |         |                     |
|  Main thread        |         |  Main thread        |
|  +---------------+  |         |  +---------------+  |
|  |               |  |         |  |               |  |
|  | $t->suspend() |  |         |  |               |  |
|  |               |  |         |  |               |  |
|  +---------------+  |         |  +---------------+  |
|                     |         |                     |
|  Created thread     |         |                     |
|  +---------------+  |         |                     |
|  |               |  |         |                     |
|  | capture()     |  |         |                     |
|  |               |  |         |                     |
|  +---------------+  |         |                     |
|                     |         |                     |
+---------------------+         +---------------------+

您声称您创建的主题未被暂停,但您几乎无法确定其是否已被暂停。毕竟,capture不会打印任何内容或更改任何外部变量。事实上,你没有理由相信它没有被暂停。

现在,你可能希望你启动的程序冻结,但是你没有做任何事情来暂停它或它的主线程。因此,它将继续运行 [1]

如果要暂停外部进程,可以向其发送SIGSTOP(以及SIGCONT以恢复它)。为此,您需要进程的PID。我建议您使用IPC::Run capture循环替换pump

  1. 好吧,它最终会在尝试写入STDOUT时阻塞,因为管道已满,因为你确实暂停了运行capture的线程。