Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re^2: Standard way to convert timezone in multithreaded script

by BrowserUk (Patriarch)
on Nov 25, 2009 at 00:55 UTC ( [id://809244]=note: print w/replies, xml ) Need Help??


in reply to Re: Standard way to convert timezone in multithreaded script
in thread Standard way to convert timezone in multithreaded script

Nice. And thanks for sharing it.

FWIW: I think the reason why POSIX::tzset() fails to work correctly in threads is because when threads are spawned, they are given their own copy of the process' environment block. But the tzset() wrapper in POSIX and the underlying CRT tzset() know nothing of those copies, hence do not honour changes made to them.

It would be possible to make the POSIX tzset() wrapper recognise that it is being called within a thread and adjust the process env block to match the calling threads prior to calling the CRT, but unless the CRT also maintained a per-thread notion of the current timezone it would be messy. One day the POSIX definition will be revamped to take account of threading.


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.

Replies are listed 'Best First'.
Re^3: Standard way to convert timezone in multithreaded script
by whale2 (Novice) on Nov 25, 2009 at 07:36 UTC
    I can't see where my XS code is aware of threads, except of calling localtime_r() instead of localtime(), but perl manuals says somewhere that if you compile perl with 'useithreads', it will automatically use those *_r() functions.

      Looking more closely at your code above, there is something strange going on that I do not understand.

      In this part of the main thread, you change the value of $ENV{TZ} twice:

      $ENV{TZ}="Europe/Paris"; my $t=localtime(); print "main (Europe/Paris): ",$t,"\n"; $ENV{TZ}="Europe/Moscow"; $t=localtime(); print "main (Europe/Moscow): ",$t,"\n";

      But nowhere in that part of the code do you call tzset(), nor any of the functions in your XS code. And yet, according to the console output you've posted:

      main (Europe/Paris): Tue Nov 24 23:27:28 2009 main (Europe/Moscow): Wed Nov 25 01:27:28 2009

      The output from localtime is somehow affected. Which is exactly what didn't happen originally that caused you to post your OP?


      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.

        XS code contains four calls to tzset()

        Perl code running in main thread works pretty well without calling POSIX::tzset. I believe this is due to how tzset()/localtime() in libc works.

        'man tzset' says "This function is automatically called by the other time conversion functions that depend on the time zone."

        So, there is no wonder why this works in main thread. And in child threads tzset needs to be explicitly called for changing timezone, but really works only when called in XS code. I don't know why, I just managed to find this fact :)

        Also, I did not tried it on other OSes or even on another linux distro or with different libc versions or versions of perl other than 5.10.0

        My environment is CentOS 5.2, libc-2.5, perl-5.10.0

        But nowhere in that part of the code do you call tzset(),

        And adding them doesn't help.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://809244]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (4)
As of 2024-04-25 05:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found