2016-07-19 1 views
0

Perl 스레드에서 직렬 포트를 사용하고 있습니다. 스레드에서 읽고 쓸 수 있습니다. 하지만 다른 응용 프로그램에서 포트를 사용하고 나중에 다시 열 수 있도록 직렬 포트를 닫고 싶다면 더 이상 읽고 쓸 수 없습니다. 그렇게하는 방법?Linux Perl 스레드 SerialPort 닫고 다시 엽니 다.

my $dev; 
my $port = "/dev/ttyACM0"; 
my $run :shared = 0; 
my $thr; 
my $read_thr; 

sub port_init 
{ 
    $dev = Device::SerialPort->new($port, 1) || die "Cannot open $port: $!\n"; 

    $dev->baudrate(115200); 
    ... 

    $run = 1; 
} 

sub read_port # read async 
{ 
    my $str; 
    while ($run == 1) 
    { 
     $str = $dev->lookfor; 
     if ($str ne "") 
     { 
      print "recv: $str\n"; 
     } 
     sleep 0.5; 
    } 
} 

sub write_port 
{ 
    my $msg = shift; 
    if ($run == 1) 
    { 
     $dev->write($msg."\r"); 
    } 
} 

sub close_port 
{ 
    $run = 0; 
    $dev->close; 
} 

# Main 
port_init(); 
$read_thr = threads->new(\&read_port); 
$read_thr->detach(); 

if ("event1 occurs") # send cmd to port 
{ 
    $thr = threads->new(\&write_port, "ATI"); # works, response received 
    $thr->detach(); 
} 

if ("event2 occurs") # another application is requesting the port 
{ 
    $thr = threads->new(\&close_port); 
    $thr->detach(); 

    # wait till application has finished 

    port_init(); 

    $read_thr = threads->new(\&read_port); 
    $read_thr->detach(); 

    # send cmd to port, doesn't work 
    $thr = threads->new(\&write_port, "ATI"); 
    $thr->detach(); 

} 

포트를 닫은 후에 더 이상 사용할 수 없습니다. read_port는 Device :: SerialPort :: input에서 오류 # 9를 두 번째로 시작한 후 throw합니다. 파서가 항상 액세스 할 수 있어야하므로 스레드가 필요합니다.

답변

0

실제 코드를 게시하지 않아도 말하기 어렵습니다.

그러나 나는 스레드가 시작하기 전에 $dev을 만들 수 있기 때문에 문제가 될 것이라고 생각 - 그리고 port_init()로 인스턴스화 - 그러나 그들은 시작할 때 각 스레드는,이 객체의 복제을 상속합니다.

이렇게하면 아주 지저분한 상태가됩니다. 먼저 이 아니라고 말하면이 먼저 도착합니다. 각 스레드는 여전히 실행 중이므로 (활성이지만 분리되어 있으므로) 포트 파일 핸들의 자체 인스턴스를 '보유'합니다.

매우 지저분하며, 이것이 제대로 작동하지 않는 이유는 거의 확실합니다.

처음에는 이런 상황에 빠지지 않을 것을 제안합니다. 그런 포트를 공유하지 말고, 모든 것을 처리하는 하나의 스레드 만 가지십시오. IPC의 공유 변수보다 복잡한 것이 필요한 경우 Thread::Queue을 사용하십시오.

관련 문제