in reply to Problem with Threaded Socket Server
If i detach the threads or join them, when they are done it crashes my serial connection to the arduino board.
You do not close the connection to your USB device before returning from your thread proc, so the symptoms above lead me to the conclusion that when Perl tries to garbage collect your thread procs -- ie. when you either join them; or immediately when you return if you detach them; it tries to DESTROY the local copy of the usb device handle $local_arduino. And that closes your connection.
You can confirm this speculation if you enable DEBUG on the device handle and you see a debug message of the form:
"Destroying $self->{NAME}" at ... etc
You might be able to work around Device::SerialPort's lack of thread-awareness by overriding its DESTROY method:
sub DESTROY { my $self = shift; return unless (defined $self->{NAME}); if ($self->{"_DEBUG"}) { carp "Destroying $self->{NAME}"; } $self->close; }
And preventing it from closing the connection unless it is the last instance of the handle; or perhaps, only if the DESTROY method is being called from the same thread as created the connection. How you would arrange to know either of these things is down to your ingenuity.
Alternatively, and more likely to work, would be to have a single thread only communicate with your USB device.
In this scenario, you start a thread which creates the connection to the USB device; and pass it a queue handle at start up. That thread the loops reading that Q waiting for command requests from other threads; enacts them; and then returns the results to the requesting threads (via a queue handle they pass along with the command request).
Your USB handling thread would look something like this:
sub USB { my $Q = shift; my $arduino = Device::SerialPort->new("/dev/serial/by-id/usb-Ardui +no__www.arduino.cc__Arduino_Mega_2560_74136333033351011152-if00"); if ( defined( $arduino ) ) { $arduino->baudrate(9600); $arduino->parity("none"); $arduino->databits(8); $arduino->stopbits(1); $arduino->read_char_time(0); $arduino->read_const_time(500); $arduino->write_settings || undef $arduino; writelog( "server:[portSet]" ); } else { writelog( "server:[portSet]: failed" ); } while( my $request = $Q->dequeue ) { my $retQ = $Q->dequeue; $arduino->write($cmd); my $answer = getLineFromArduino() $retQ->enqueue( $answer ); } }
To make requests, your client threads then do:
sub client { my $client = shift; my $usbQ = shift; my $retQ = new Thread::Queue; ... my $command = <$client>; $usbQ->enqueue( $command, $retQ ); my $result = $retQ->dequeue; print $client $result; ... }
Season to taste with logging and error handling.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Problem with Threaded Socket Server
by piece (Novice) on Aug 18, 2013 at 20:34 UTC | |
by BrowserUk (Patriarch) on Aug 18, 2013 at 20:47 UTC | |
by BrowserUk (Patriarch) on Aug 18, 2013 at 21:04 UTC | |
by piece (Novice) on Aug 18, 2013 at 21:29 UTC | |
by BrowserUk (Patriarch) on Aug 18, 2013 at 21:45 UTC |