2014-12-03 2 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

참조 [펄 스레드입니다 스레드의 종류는?] (http://perldoc.perl.org/perlthrtut.html#What-kind-of-threads-are-Perl-threads%3f)에의 선적 서류 비치. – choroba

답변

3

$thread->_handleHANDLE*을, 이상 SetThreadPriorityHANDLE을 기꺼이 반환합니다. 다음과 같이 당신이 할 수있는 포인터를 역 참조 할 필요가 :

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

+0

업데이트 할 생각이지만,이 단계에서는 더 이상 변경할 수 없습니다. 그 종류의 threads.pm : - / –

0

무엇 _handle 반환하는 것은 무엇인가는 Win32 아니라는 것을 알 수 ERROR_INVALID_HANDLE

:: API는 이해한다. 나는 "P"가 integer-casted 포인터가 아닌 문자열 버퍼를 원한다고 생각한다. 64 비트에서 크기가 잘못 되었기 때문에 "나"는 잘못된 것일 수 있습니다. 나는 "N"을 시도 할 것입니다.

또한 Unix에서이 문제가 발생하는 독자를 위해 : POSIX::RT::Scheduler 모듈을 사용해보십시오.

+0

'N '어떤 Win32 :: API 문서가 포인터와 같은 정수로 문서화됩니다. 진짜 문제는,'_handle'이'HANDLE * '을 리턴하지만'SetThreadPriority'는'HANDLE'을 기대한다는 것입니다. – ikegami

+0

성공하지 않고 POSIX :: RT :: Scheduler를 컴파일하려고 시도했습니다. ( – tals