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

I've encountered strange behavior in a script, where I read and write to the same variable repeatably and rapidly. It seems the issue is that the read operation happens before the previous write finishes, and I get errors. Example code:

my @array = ( some values ); While ( my_condition ) { $buffer = $array[0]; $array[0] = new_value; mytestfunc(\@array); $array[0] = $buffer; }

Before long, $array[0] != $buffer. But, if I change the code to the following, my errors disappear.

While ( my_condition ) { $buffer = $array[0]; $array[0] = new_value; mytestfunc(\@array); $array[0] = $buffer while ($array[0] != $buffer); }

Is there a better way to handle this issue? Thanks for the wisdom and advice.

Jeff

Replies are listed 'Best First'.
Re: volatile memory?
by rovf (Priest) on Sep 02, 2010 at 07:56 UTC
    Unless you use parallel threads which mysteriously change the value of $buffer, I don't think that Perl gets "out of sync" when writing your memory. You did not specify at which point $buffer is not equal to $array[0]. Of course there are some parts in your program where these variables are potentially not equal (for example, during the execution of mytestfunc).

    BTW, are you sure that we are talking about numerical unequality, and not string unequality? I.e., $buffer contains always a number, right? Because you are using != and not ne.

    -- 
    Ronald Fischer <ynnor@mm.st>

      I'm not intentionally using multiple threads, though the computer is dual core.

      The error occurs within the loop; every so often, $array[0] contains the wrong value (yes, numeric), but always a previously used value. In tests, only about 20% of the values were wrong, the others right. And the second while loop solved the errors. I don't know how to explain that, really.

      mytestfunc only reads values from the array, and does not change it.

        Hi kjcdb8er, I just set up a little test to prove the fast assignment and reassignment of values in the array:
        # 858508.pl use strict; use warnings; use 5.010; my @array_old = my @array = ( 1 .. 10e3 ); for my $i ( 0 .. $#array ) { my $buffer = $array[$i]; $array[$i] = new_value(); $array[$i] = $buffer; } if( @array_old ~~ @array ) { say "arrays are equal"; } else { say "array are different"; } sub new_value { rand(); }
        This code creates an array of consequtive numbers from 1 to 10000 and changes every number to a random value and restores the initial value. I wasn't able to reproduce your problem. I suppose the problem you are facing is located on the different code part as you showed.
        You can post the complete code so that others can run your code on their machine.
Re: volatile memory?
by DrHyde (Prior) on Sep 02, 2010 at 09:56 UTC

    Of course, in between $array[0] = new_value; and $array[0] = $buffer;, you can expect their values to differ.

    Either you're not measuring what you think you're measuring, or you're dealing with a tied variable or an object that overloads some operators, in which case all bets about how things should behave are off.

Re: volatile memory?
by JavaFan (Canon) on Sep 02, 2010 at 10:49 UTC
    Could you post a short, but complete, program that exhibits the behaviour? For instance, your code fragment show $buffer to be scoped outside of the while loop, while the code doesn't show sub new_value or sub mytestfunc. Or even my_condition. If any of those functions modifies $buffer, you have your answer.