Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl Thread Safe Modules

I am trying to take a Perl program I wrote and thread it. The problem is I read that some modules aren't "thread safe". How do I know if a module is thread safe? I've looked around for a list and cannot locate one.

To test out one module I use frequently (Text::CSV_XS) I tried the following code out:

use strict;
use warnings;
use threads;
use threads::shared;
require Text::CSV_XS;

my $CSV = Text::CSV_XS->new ({ binary => 1, eol => "\n" }) or die("Cannot use CSV: ".Text::CSV->error_diag());
open my $OUTPUT , ">:encoding(utf8)", "test.csv" or die("test.csv: $!");

share($CSV);

my $thr1 = threads->create(\&sayHello('1'));
my $thr2 = threads->create(\&sayHello('2'));
my $thr3 = threads->create(\&sayHello('3'));


sub sayHello
{
 my($num) = @_;

 print("Hello thread number: $num\n");

 my @row = ($num); 
  lock($CSV);{
   $CSV->print($OUTPUT, \@row);
   $OUTPUT->autoflush(1);
  }#lock
}#sayHello

The output I receive is the following:

Hello thread number: 1
Segmentation fault

Does this mean the module is not thread safe, or is it another problem?

Thanks

like image 913
user387049 Avatar asked Jul 20 '10 02:07

user387049


People also ask

What are thread-safe libraries?

Thread safe: Implementation is guaranteed to be free of race conditions when accessed by multiple threads simultaneously. Conditionally safe: Different threads can access different objects simultaneously, and access to shared data is protected from race conditions.

Does Perl support multithreading?

Perl can do asynchronous programming with modules like IO::Async or Coro, but it's single threaded. You can compile Perl with threads, which provide multi-threaded computing.

Should I use thread-safe or non thread-safe?

Thread-safety is recommended when the web server run multiple threads of execution simultaneously for different requests. In Thread Safety binary can work in a multi-threaded web server context. Thread Safety works by creating a local storage copy in each thread so that the data will not collide with another thread.

What is a thread-safe object?

A thread-safe object is one that always maintains a valid state, as observed by other classes and objects, even in a multithreaded environment.


1 Answers

Generally speaking, core and high-visibility modules are thread-safe unless their documentation says otherwise.

That said, there are a few missteps in your post:

  1. share($CSV)
    This clears $CSV (a blessed hashref), just as documented in threads. Generally, you want to share() complex objects prior to initialization or, perhaps in this case, share() some dumb $lock variable between threads.
    Since $CSV holds state for the underlying XS, this might lead to undefined behavior.

    But this isn't your segfault.

  2. threads->create(\&sayHello('1'));
    You are mistakenly invoking sayHello(1) in the main thread and passing a reference to its return value to threads->create() as a (bogus) start routine. You meant to say:

    threads->create(\&sayHello, '1');
    

    But this isn't your segfault.

    (EDIT Just to clarify -- a bad start routine here doesn't risk a SEGV in any case. threads::create properly complains if an unrecognized subroutine name or non-CODE ref is passed in. In your case, however, you are segfaulting too quickly to reach this error handling.)

  3. Encodings are not thread-safe.
    Again as documented in encodings, the encoding module is not thread-safe. Here's the smallest possible code I could get to reproduce your symptoms:

    use threads;
    open my $OUTPUT , ">:encoding(utf8)", "/dev/null" or die $!;
    threads->create( sub {} )->join;
    

    That's perl 5.12.1 with threads-1.77 on i686-linux-thread-multi, if you're interested. Drop the "utf8" magic, and it works just fine.

    This is your segfault

like image 166
pilcrow Avatar answered Oct 05 '22 15:10

pilcrow