我在Perl线程中使用串行端口,我可以在线程中读写。但是如果我想关闭串口以便其他应用程序可以使用该端口并在以后再打开它,我就不能再读写了。怎么做?
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。我需要Threads,因为解析器必须始终可访问。
答案 0 :(得分:0)
好吧,如果没有发布实际代码 - 很难说。
但是我认为问题将是因为你在线程开始之前创建$dev
- 并用port_init()
实例化它 - 但是每个线程都继承了一个 clone < / em>这个对象,当他们开始时。
这让你处于一个非常混乱的状态 - 我强烈建议不首先进入。因为每个线程仍然在运行 - 它是活动的,但是已经分离 - 因此将会保持&#39;它自己的端口文件句柄实例。
这非常混乱,几乎可以肯定这是为什么它不能正常工作。
我建议你不要首先进入这种情况 - 不要共享这样的端口,只需要一个处理整个事情的线程。如果您需要比IPC的共享变量更复杂的东西,请使用Thread::Queue
。