1

你好点子,

我有一个 Tkx gui,它使用按钮运行批处理文件。批处理文件在不同的线程中执行,因为我希望 GUI 仍然可用。我想实现一个取消按钮来取消批处理文件的执行。

我尝试发送一个 Kill 信号,但它只会终止线程而不是批处理文件。下面是运行和取消子程序的代码。

哦,我不允许编辑批处理文件。

my $t1;
sub runbutton{
    $bar->g_grid();
    $bar->start();
    $t1 = threads->create(sub { 
        local $SIG{'KILL'} = sub { threads->exit };
        system("timer.bat"); 
        
        });
    
    $t1->set_thread_exit_only(1);
    my $start = time;
    my $end = time;
    while ($t1->is_running()) { 
        $end = time();
        $mytext = sprintf("%.2f\n", $end - $start);
        Tkx::update(); 
   }
   
    $bar->stop();
    $bar->g_grid_forget();
    $b4->g_grid_forget();
}

sub cancelbutton
{
    $t1->kill('KILL')->detach();
}
4

2 回答 2

1

你在 Windows运行它,因为你说“批处理”?

我相信你必须使用特定于操作系统的工具来“识别”和“杀死”进程,例如 pslist/pskill (sysinternals)

于 2014-05-09T05:19:55.023 回答
0

我怀疑 Perl 线程在执行“触发”终止信号之前正在等待系统返回。

我建议使用 Win32::Process 将批处理文件作为一个单独的进程启动,然后有一个变量来表示应该终止该进程。设置变量后,线程可以杀死进程然后退出。

这是我使用 Win::Process 使用 Active State Perl 版本 5.16.1 创建和终止批处理文件作为单独进程的小测试用例:

use strict;

# Modules needed for items
use Win32::Process;
use Win32;

# Subroutine to format the last error message which occurred
sub ErrorReport
{
    print Win32::FormatMessage( Win32::GetLastError() );
}

print "Starting Process\n";

# Declare a scalar for the process object
my $ProcessObj;

# Create the process to run the batch file
Win32::Process::Create($ProcessObj,
    "C:\\Users\\Glenn\\temp.bat",
    "C:\\Users\\Glenn\\temp.bat",0,
    NORMAL_PROIRITY_CLASS,
    ".") || ErrorReport();

print "Process Started\n";

# Sleep for a few seconds to let items start running
sleep(2);

# Kill the process with a -9
# $ProcessObj->Kill(0) does not seem to work to stop the 
# process.  Kill will kill the process with the process id 
kill -9,$ProcessObj->GetProcessID();

# Done with efforts
print "Complete\n";

如果您使用的是 Windows 7,则需要以管理员身份运行以允许创建进程,否则在尝试创建进程时会收到拒绝访问消息。

于 2014-05-09T13:23:39.460 回答