Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

to "use vars" or not to

by westy032001 (Novice)
on Nov 08, 2010 at 17:29 UTC ( [id://870156] : perlquestion . print w/replies, xml ) Need Help??

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

Dear monks I need help (again),

Scenario is. I have a process listening which when it receives an input it forks and runs a module which inputs the data into a database.

In this module (package name DB_input ) i have used “use vars qw($dbh $timestamp $server)" . I am occasionally having mangled data go into the database and i wonder if it is because of the “use vars” ? Is it possible that when the listener forks 2 or more children at the same time, that the variables defined by “use vars” can end up being shared between the forked children ?

In which case would using "our" be better as i understand it is more tightly scoped ? thank you .

Replies are listed 'Best First'.
Re: to "use vars" or not to
by Corion (Patriarch) on Nov 08, 2010 at 17:37 UTC

    No. That's not how fork works.

    use vars; creates a global variable and its value gets copied into every child spawned by fork. Usually, mixing fork and DBI is a bad idea unless you read the DBI documentation closely. I recommend you do that.

    Using global variables always creates the possibility of action at a (long) distance, so restricting the scope of variables is a good approach to reducing the distance over which action can influence the values. our won't help much because it still creates global variables that can be changed from elsewhere. If you want more protection, consider using lexical variables, as declared with my.

    If you want more concrete help, post concrete code that exhibits your problem. It should not be longer than 20 lines and not require outside data files.

Re: to "use vars" or not to
by ikegami (Patriarch) on Nov 08, 2010 at 17:40 UTC

    $dbh, $timestamp and $server don't sound like variables that should be used from outside the package, so use vars isn't appropriate. They don't sound like they need to be package variables, so our isn't appropriate. my should be used here. (Actually, it would probably make a lot more sense for those to be attributes of any object.)

    variables defined by “use vars” can end up being shared between the forked children ?

    Variables aren't shared between processes. Each child gets a byte-for-byte copy.

    I am occasionally having mangled data go into the database

    It doesn't make sense for two processes to use the same database connection. Open a connection in each child.

      Thank you for your quick response .

      All of my DBI code exists in the module run by the child forked from the listener and so I dont intend to share a connection, but by setting the $dbh globaly in the module run by the child am i causing it to be inherited by the next forked child ?


        You seem to be unclear about what fork does, in Perl and on many operating systems. See Fork (operating system) for a more general introduction. If you are on Windows, it's best to avoid fork overall, especially when trying to use DBI.

Re: to "use vars" or not to
by sundialsvc4 (Abbot) on Nov 08, 2010 at 21:45 UTC

    You imply that the process forks for each request received, and that the forked copy attempts to do an insert.

    This is a strategy that is, IMHO, inherently unstable (and easily “flooded”).

    A much better strategy would be to have an app that simply consists of two threads or processes:

    • The main, or “listener,” thread waits for requests to arrive.   When they do, it writes a record to a queue.
    • The child, or “writer” thread waits for a message to arrive in the queue, then posts it to the database.

    So, if a flood of inputs comes in, they simply pile-up (briefly...) in the queue.   The writer-process disposes of them as quickly as it can ... while never overwhelming the underlying database server.   The listener-process can reply immediately, saying in effect that “your request has been accepted,” knowing that the writer will “lazily” post it to the database.   From the database server’s point of view, this app might be a “busy” client, but it is also an “uncomplicated” one.

Re: to "use vars" or not to
by 7stud (Deacon) on Nov 08, 2010 at 21:51 UTC
    use strict; #<--**** use warnings; #<---***

    Declaring global variables using fully qualified names:

    $main::x = 10; print $main::x, "\n"; #10

    Above okay under use strict.

    Declaring global variables with use vars:

    use vars qw{$x}; print $x, "\n"; #10

    'use vars' provides a shortcut: you don't need to use the fully qualified variable name, which is what use strict requires.

    Declaring global variables with our:

    # $y = 'hello'; #error under use strict our $y = 'hello'; print $y, "\n"; #hello

    Once again, our provides a shortcut to having to use fully qualified names under use strict.

    What's the difference between our and use vars?

    { our $z = 5; print $z, "\n"; #5 } # print $z, "\n"; #error print $main::z, "\n"; #5 { use vars qw{$s}; $s = 'bye'; print $s, "\n"; #bye } print $s, "\n"; #bye

    'use vars' has file scope, i.e. it applies to the whole file, and cannot be undone (e.g. with 'no use vars')--while our has block scope, so the short form of the variable name only works within the same block as the our statement.

    Note that the global variable always exists no matter what method you use--the issue is whether you can refer to the global variable using the short form of the variable name or not.