in reply to Writing threadsafe perl extensions

As with most of these 'non-threadsafe' problems, it is the near useless process of implicit cloning, that is at fault. If you avoid it, and manually load the code into the thread where it is used, it works fine:

#! perl -slw use strict; use threads; sub t { require Math::Pari; eval { use Math::BigInt; }; my $mbi = Math::BigInt->new( $_[ 0 ] ); $mbi /= 11; return $mbi; } print threads->create( \&t, '123' x 11 )->join; __END__ c:\test>t-pari 11193011193011193011193011193011

Using Math::BigInt without Math::Pari in multiple threads this way also works:

#! perl -slw use strict; use threads; sub t { # require Math::Pari; eval { use Math::BigInt; }; my $mbi = Math::BigInt->new( $_[ 0 ] ); $mbi /= 11; return $mbi; } print threads->create( \&t, '123' x 11 )->join; print threads->create( \&t, '123' x 21 )->join; __END__ c:\test>t-pari 11193011193011193011193011193011 11193011193011193011193011193011193011193011193011193011193011

But with Math::Pari it does not. This code hangs:

#! perl -slw use strict; use threads; sub t { require Math::Pari; eval { use Math::BigInt; }; my $mbi = Math::BigInt->new( $_[ 0 ] ); $mbi /= 11; return $mbi; } print threads->create( \&t, '123' x 11 )->join; print threads->create( \&t, '123' x 21 )->join; __END__ c:\test>t-pari 11193011193011193011193011193011 Terminating on signal SIGINT(2)

Which seems to put the problem within Math::Pari. The following from the Math Pari POD may give some indication to the cause:

Legacy implementations of dynalinking require the code of DLL to be compiled to be "position independent" code (PIC). This slows down the execution, while allowing sharing the loaded copy of the DLL between different processes. On contemeporary architectures the same effect is allowed without the position-independent hack.

Currently, PARI assembler files are not position-independent. When compiled for the dynamic linking on legacy systems, this creates a DLL which cannot be shared between processes. Some legacy systems are reported to recognize this situation, and load the DLL as a non-shared module. However, there may be systems (are there?) on which this can cause some "problems".

Summary: if the dynaloading on your system requires some kind of C<-fPIC> flag, using "assembler" compiles (anything but C<machine=none>) *may* force you to do a static build (i.e., creation of a custom Perl executable with

perl Makefile.PL static make perl make test_static
).

I don't have Math::GMP, so I haven't checked whether any of hthis translates to that module.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."

Replies are listed 'Best First'.
Re^2: Writing threadsafe perl extensions
by syphilis (Archbishop) on Oct 21, 2007 at 13:47 UTC
    I don't have Math::GMP, so I haven't checked whether any of this translates to that module

    Pity ... that's the one I'm most interested in :-)
    Given that the following script works fine:
    #!perl -slw use Math::GMP; my $ret = Math::GMP->new('123' x 11); print Math::GMP::get_str_gmp($ret, 10); __END__ C:\_32\pscrpt\threads>perl gmp2.pl 123123123123123123123123123123123
    if Math::GMP were threadsafe, would you expect that the following also outputs the same:
    #!perl -slw use threads; use Math::GMP; sub t1 { my $mbi = Math::GMP->new($_[0]); return $mbi; } my $th1 = threads->new(\&t1, '123' x 11); my $ret1 = $th1->join; print Math::GMP::get_str_gmp($ret1, 10);
    (It doesn't - it just segfaults.) Does that therefore prove that Math::GMP is not threadsafe ? - or is there yet a possible rendition that may prove fruitful ?

    Cheers,
    Rob

      What happens with this?

      #!perl -slw use threads; sub t1 { eval{ use Math::GMP }; my $mbi = Math::GMP->new($_[0]); return $mbi; } my $th1 = threads->new(\&t1, '123' x 11); my $ret1 = $th1->join; print Math::GMP::get_str_gmp($ret1, 10);

      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        What happens with this?

        Still segfaults, unfortunately.

        Cheers,
        Rob