2014-12-03 182 views
1

我試圖在腳本中更改線程優先級,但沒有成功,這裏是詳細信息。更改線程優先級ERROR_INVALID_HANDLE

$thr = threads->new(\&someFunction, 
        $shared variable 1, 
        $shared variable 2, 
        ); 

我試過使用threads::State;

$thr->priority(2); 

沒有成功

所以,我認爲Win32::API必須努力

my $functionGetLastError= Win32::API->new('Kernel32', 
              'GetLastError', 
              '', 
              'N' 
             ); 
my $functionSetThreadPriority= Win32::API->new('Kernel32', 
               'SetThreadPriority', 
               'II', # I've tried 'PI' and 'II' as well 
               'N' 
              ); 
my $h = $thr->_handle(); 
my $success = $functionSetThreadPriority->Call($h, 2); 
warn "Return Error #".$functionGetLastError->Call() if !$success; 

再次,沒有成功:(,但現在我有一個線索,該腳本返回錯誤號

最後錯誤6

MSDN site, System Error Codes (0-499),似乎錯誤是

ERROR_INVALID_HANDLE

我在做什麼錯?

+0

參見[什麼樣的線程是Perl的線程?](http://perldoc.perl.org/perlthrtut.html#What-kind-of-threads-are-Perl-threads%3f)在文檔。 – choroba 2014-12-03 13:37:27

回答

3

$thread->_handle奇怪地返回HANDLE*,而SetThreadPriority預計HANDLE。您需要取消引用指針,你可以做如下:

use constant THREAD_PRIORITY_HIGHEST => 2; 

sub SetThreadPriority { 
    my ($thread, $priority) = @_; 

    # $thread->_handle() returns a HANDLE*. 
    my $handle_ptr = $thread->_handle(); 
    my $packed_handle = unpack('P'.HANDLE_SIZE, pack(PTR_FORMAT, $handle_ptr)); 
    my $handle  = unpack(HANDLE_FORMAT, $packed_handle); 

    state $SetThreadPriority = (
     Win32::API->new('Kernel32', 'SetThreadPriority', 'Ni', 'i') 
     or die("Loading SetThreadPriority: $^E\n") 
    ); 

    return $SetThreadPriority->Call($handle, $priority); 
} 

下面是完整的測試程序:

,您可以使用 $^E
use strict; 
use warnings; 
use feature qw(say state); 

use threads; 
use threads::shared; 

use Carp  qw(croak); 
use Config  qw(%Config); 
use Win32::API qw(); 

sub uint_format { 
    $_[0] == 4 ? 'L' 
    : $_[0] == 8 ? 'Q' 
    : croak("Unsupported") 
} 

use constant PTR_SIZE => $Config{ptrsize}; 
use constant PTR_FORMAT => uint_format(PTR_SIZE); 

use constant HANDLE_SIZE => PTR_SIZE; 
use constant HANDLE_FORMAT => PTR_FORMAT; 

use constant THREAD_PRIORITY_HIGHEST => 2; 

sub SetThreadPriority { 
    my ($thread, $priority) = @_; 

    # $thread->_handle() returns a HANDLE*. 
    my $handle_ptr = $thread->_handle(); 
    my $packed_handle = unpack('P'.HANDLE_SIZE, pack(PTR_FORMAT, $handle_ptr)); 
    my $handle  = unpack(HANDLE_FORMAT, $packed_handle); 

    state $SetThreadPriority = (
     Win32::API->new('Kernel32', 'SetThreadPriority', 'Ni', 'i') 
     or die("Loading SetThreadPriority: $^E\n") 
    ); 

    return $SetThreadPriority->Call($handle, $priority); 
} 

{ 
    my $done :shared = 0; 

    my $thread = async { 
     { lock($done); cond_wait($done) while !$done; } 
    }; 

    my $rv = SetThreadPriority($thread, THREAD_PRIORITY_HIGHEST); 
    say $rv ? "Success" : "Error: $^E"; 

    { lock($done); $done = 1; cond_broadcast($done); } 
    $thread->join(); 
} 

公告訪問GetLastError

SetThreadPriority($handle, THREAD_PRIORITY_HIGHEST) 
    or die("SetThreadPriority: $^E\n"; 
+0

@ user2842165,更新 – ikegami 2014-12-03 17:02:57

+0

我會說這是一個錯誤,但賠率是,不能再在這個階段發生變化,不是第一那種在threads.pm中: - / – 2014-12-04 03:51:47

0

ERROR_INVALID_HANDLE

這表明什麼_handle返回是不是的Win32 API ::理解。我懷疑「P」想要一個字符串緩衝區而不是一個整數轉換的指針。 「我」可能是錯誤的東西,因爲它在64位上的大小是錯誤的,我會自己嘗試「N」。

此外,對於將來在Unix上遇到此問題的讀者:請嘗試我的POSIX::RT::Scheduler模塊。

+0

'N'什麼Win32 :: API文件作爲一個指針的整數等價物。但真正的問題是'_handle'返回'HANDLE *',但'SetThreadPriority'需要一個'HANDLE'。 – ikegami 2014-12-03 17:18:54

+0

我試圖編譯POSIX :: RT ::計劃,但沒有成功:( – tals 2014-12-04 06:56:54