Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Perl should start to specify which functions and modules are thread-safe

by pg (Canon)
on Feb 02, 2003 at 18:41 UTC ( [id://232024]=perlmeditation: print w/replies, xml ) Need Help??

As we saw in c, it always specifies what is safe with thread, what is unsafe. For example, strtok is unsafe with thread.

Perl does not do this, and this is extreamly dangerous. Of course, it is not a surprise to me, as Perl only started to have this real thread stuff since 5.8. However Perl should start this ASAP, otherwise it will bite everyone.

For example, I found Tie::File is not safe with thread. Try the following code on win32, see how account.txt is messed up.

use Tie::File; use threads; use strict; use constant NUMBER_OF_THREAD => 10; $|++; open(ACCOUNT, ">", "account.txt"); foreach (0..NUMBER_OF_THREAD) { print ACCOUNT "1000\n"; } close(ACCOUNT); tie my @account, "Tie::File", "account.txt" or die "cannot tie\n"; foreach (1..NUMBER_OF_THREAD) { my $kid = threads->create(\&thread_job, $_); $kid->detach(); } untie @account; sub thread_job { my $id = shift(); print "I am a child, this is the name my parents gave me: ", $id, +"\n"; while (1) { $account[$id] -= 100; $account[$id] += 100; } }


Foot Notes:

This post is for a general purpose, and it is not about Tie::File. Tie::File is just an example, and is the point where I started to think about this.

  • Comment on Perl should start to specify which functions and modules are thread-safe
  • Download Code

Replies are listed 'Best First'.
Re: Perl should start to specify which function and module are thread-safe
by integral (Hermit) on Feb 02, 2003 at 19:58 UTC
    Tie::File is a bit different from a standard library function. The reason strtok isn't thread-safe is that it stores data in an internal static variable that is shared by the whole process, and isn't thread-local. The usual way to make something like this thread safe is to either eliminate the buffer or make the user of the function pass in the buffer to be used, allowing them to make sure its thread-local. This means that the function itself doesn't contain any thread-handling code, and places this burden on the user.

    The difference between Tie::File and a library function is clear. Tie::File explicitly stores information between calls. Once you know that Tie::File stores data and doesn't use locking, it should be immediately clear that using it without your own locking on the variable is not thread-safe.

    If you're using threads it should be the responsibility of the user to handle locking on shared variables as this allows consistency across their application and they can handle the hard bits like dead-lock resolution.

    --
    integral, resident of freenode's #perl
    
      I understand what you said and fully agree with you. Your comment definitely made this thread more complete.

      However the situation here is a little bit more complex than what you just stated.

      From my application point of view, locking is not a problem. As you can see, I didn't use any lock at all, because each child thread will only access that array element belongs to it, so lock is not required from my point of view, or to be precise, my application's point of view.

      Now as for the internals used by Tie::File. I don't care, and I SHOULD NOT care. Although I read the code of that module before, but that is not required for using the module, thus there is no way to require the user to help lock Tie::File internals, as he/she most likely has no appreciation of what is going on in that module.

      If my logic requires some lock, the only thing I would and I am supposed to lock is @array, not any Tie::File internals.

      As for those Tie::File internals, if the author wants to make his package thread-safe, go do something, redesign it, apply lock whenever it is required ...

      Yes, to make a OO module thread-safe is a much bigger challenge than to make a usual function thread-safe, and this is my experience with c++ classes and pthread. This is for sure, and this most likely would require fundamental changes to Perl OO, (and I am thinking probably even the way perl variables are scoped, especially the main:: scope)
        My point of view is that it should be the job of the module writer to guess every possible situation of when a object. And this applies fine was a simple object like the Employee or Person often used in OO tuts. But it begins to break down when you get objects which could benefit from higher-grain locks. My approach would not to include locking in the core modules since this increases overhead in the large number of applications with threads, but to instead use an adaptor or subclass to wrap locks around each record and to manage them.

        You make a good point that by encapsulation you shouldn't need to know about locking, but surely the core algorithms for mapping a file to an array don't need to know about thread locking? This would be best served by adding another layer on top of the existing class.

        --
        integral, resident of freenode's #perl
        
Re: Perl should start to specify which functions and modules are thread-safe
by zentara (Archbishop) on Feb 03, 2003 at 15:37 UTC
    I'm just starting to learn about threads myself, but have you looked at the Threads modules on cpan, it looks like Thread-Tie and Thread-Use seems to apply to your situation. It looks like Elizabeth Mattijsen is trying to work thru alot of these issues.

    From the perlthrtut: If you're using a module that's not thread-safe for some reason, you can protect yourself by using it from one, and only one thread at all. If you need multiple threads to access such a module, you can use semaphores and lots of programming discipline to control access to it.

    I guess the conventional wisdom, is if your app needs to keeps variable data separate, use a forked model. If your app needs to share variable data, use a threads model.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://232024]
Approved by JaWi
Front-paged by mattriff
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (5)
As of 2024-04-19 18:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found