Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Thread safe equivalent of LINUX touch command

by ISAI student (Scribe)
on Nov 22, 2012 at 14:27 UTC ( [id://1005135]=perlquestion: print w/replies, xml ) Need Help??

ISAI student has asked for the wisdom of the Perl Monks concerning the following question:

Hello all. I am making an old script thread safe, and prefrably w/o direct system( ) commands/ One of the lines involve system ("touch $file"). How do I do that which is thread safe and PERLish?
  • Comment on Thread safe equivalent of LINUX touch command

Replies are listed 'Best First'.
Re: Thread safe equivalent of LINUX touch command
by BrowserUk (Patriarch) on Nov 22, 2012 at 15:11 UTC

    What do you mean by "thread-safe"?

    If two threads attempt to touch the same file, first one will succeed(*), and then the other will succeed(*).

    Of course, it will be impossible to know which thread succeeded first (or last), but the files timestamps will have changed.

    And whichever order they do it in, the file will have been touched twice as programmed.

    How do you want to define "not thread-safe"?

    (*)Where "success" is defined as altering the timestamps on the file to some value.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    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.

    RIP Neil Armstrong

      BrowserUk,

      Happy Thanksgiving!

      Same result with 'fork' and if two or more users executed the script from the command line. I guess I think of "?-save" as that you don't allow a race condition to exist, and must use locking to prevent the race condition.

      Regards...Ed

      "Well done is better than well said." - Benjamin Franklin

        I guess I think of "?-save" as that you don't allow a race condition to exist, and must use locking to prevent the race condition.

        In order for the potential for a "race condition" to exist, several algorithmic prerequisites are needed:

        1. Two (or more) execution contexts (EC*) need to concurrently access shared storage,
        2. Those ECs need to write to that shared storage.
        3. The values they write need to be derived from a value previously read from (the same or different) shared storage.

        These algorithmic prerequisites are required because:

        • If no writes occur, there is no race condition.
        • If the writes are not to a shared location, there is no race condition.
        • If the values written are not derived from a value held in shared storage, there is no race condition.

        As (the normal meaning of) 'touching a file' does not require any of these, a "race condition" cannot occur.

        That said, it is possible to contrive a bespoke "touch" requirement that could introduce a race condition. For example, an algorithm might require that not just the 'modified' timestamp be set; but also, one, the other, or both of the other two timestamps be set to the same value.

        In the case, if the OS, or the tool, required multiple calls to set multiple timestamps, it would be possible for one thread to modify one of the TSs, then get swapped out; then a second thread modifies all of the affected TSs; and then the first thread gets another timeslice and modifies the other one or two TSs.

        The result would be that the file would get a mismatched set of timestamps.

        The windows SetFileTime system call (can) set all three in one call, thus preventing that possibility, but that does not prevent a particular implementation of 'touch' from choosing to call the function multiple times to set multiple timestamps, in which case a race condition would be introduced.

        And I don't know if other OSs can update multiple timestamps as an atomic operation or not.

        Hence, to really answer the OPs question, it will be necessary for him to answer my question and clarify exactly what he is doing with his 'touch' operation.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        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.

        RIP Neil Armstrong

        The values they write need to be derived from a value previously read from (the same or different) shared storage.
Re: Thread safe equivalent of LINUX touch command
by flexvault (Monsignor) on Nov 22, 2012 at 14:59 UTC

    ISAI student,

    I have a common module that includes the following:

    sub Touch { my $file = shift; open ( my $TOUCH,">>",$file ) || Die_Rtn( 23, "$Caller: ! open fail +ure on |$file|"); close $TOUCH; }

    In your code you call it the same way as you do now. Make sure you have the ">>" or you'll clear the file. Note: On some older *nix systems, I've had to actually do I/O to the file. In that case, I'd 'print' a "\n" to the end before closing. I didn't like that solution, but it did work and didn't cause any *KNOWN* problems.

    I have used mostly 'fork', so I've never tried this with Threads, so others may suggest an alternative, but this works and is faster than calling the system 'touch'. 'Die_Rtn' is also in the common module and determines if the failure is for the user or the system and acts accordingly.

    Hope this helps!

    "Well done is better than well said." - Benjamin Franklin

Re: Thread safe equivalent of LINUX touch command
by RichardK (Parson) on Nov 22, 2012 at 15:48 UTC

    Does utime do what you need?

    the help says :-

    For example, this code has the same effect as the Unix touch(1) comman +d when the files already exist and belong to the user running the program: #!/usr/bin/perl $atime = $mtime = time; utime $atime, $mtime, @ARGV;

    Don't know about thread safety though, but why would you care ?

      utime will not create the file if it does not exist; that is one difference with touch.

      Dum Spiro Spero
Re: Thread safe equivalent of LINUX touch command
by space_monk (Chaplain) on Nov 22, 2012 at 14:47 UTC

    Would you believe using File::Touch ? :-)

    A Monk aims to give answers to those who have none, and to learn from those who know more.

      There is no way that File::Touch is thread-safe(*).

      (*)I don't think the OP actually means "thread-safe" either, but that may become clearer in time.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      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.

      RIP Neil Armstrong

        Why not? AFAICT, if one thread touches a file then it will succeed, and if another thread tries to touch a file, then it too will succeed. There is nothing wrong in both threads succeeding and I don't think there is any lock issues apart from the actual creation of the file and/or setting of the modification date, which are probably operating/filesystem issues and should be thread safe in any event.
        A Monk aims to give answers to those who have none, and to learn from those who know more.
Re: Thread safe equivalent of LINUX touch command
by ColonelPanic (Friar) on Nov 22, 2012 at 14:50 UTC
    How about opening the file for appending, then immediately closing it?
    open my $fh, '>>', 'file.txt' or die "Ouch: $!"; close $fh;
    Not tested (I'm on Windows and think this might be system-dependent).


    When's the last time you used duct tape on a duct? --Larry Wall

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (2)
As of 2024-04-25 19:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found