[Melbourne-pm] Use of each() on hash after insertion without resetting hash interator results in undefined behavior

Toby Corkindale toby.corkindale at strategicdata.com.au
Sun Oct 19 21:52:32 PDT 2014


Hi Andre,
In my experience, Perl threads don't work properly. Not just my opinion either --the official stance is that their use is "strongly discouraged".

To avoid the error you're seeing, I think you'd need a mutex lock around the hash access, ie. so that the foreach loop can't run at the same time as the hash insertion -- except that if you're going to do that, then your program may as well be single threaded.
Consider rewriting your code to use forking with a queue if you're after performance and reliability.
If you do stick with threads, then you also need to take more care around race conditions - for instance, consider what happens if a requestid is added to the hash for a second time, while the first time is being processed in doSomeMagic().

Cheers,
Toby

----- Original Message -----
> From: "Alexandre Andrade" <alexandre.andrade at ecetera.com.au>
> To: melbourne-pm at pm.org
> Sent: Monday, 20 October, 2014 3:27:02 PM
> Subject: [Melbourne-pm] Use of each() on hash after insertion without resetting hash interator results in undefined
> behavior
> 
> Hi Folks,
> I'm using Perl v5.20.0 for sun4-solaris-thread-multi-64 on Solaris 11.
> I have a main thread that reads from disk and adds some values to a Shared
> Hash and a secondary thread that goes through that Hash, uses some values
> and delete the used values from the hash.
> Something like this:
> 
> # This Thread will run in paralel and check the Memory Hash for completed
> transactions and do some tricks
> my $ thr = threads -> new ( \ &check_time );
> while ( defined ( my $ line = $ file -> read )) {
> my @ transaction_details : shared ;
> .
> .
> .
> $ transactions { $ transaction ->{ "RequestId" } } = \ @ transaction_details
> ;
> }
> sub check_time () {
> while ( 1 ) {
> {
> foreach my $ key ( keys ( % transactions ) ) {
> doSomeMagic( $ transactions { $ key } );
> delete ( $ transactions { $ key });
> # Abandoning the Foreach Loop as I've changed the %transactions memory map
> last ;
> }
> sleep(1);
> }
> }
> 
> --
> The code works but the warning:
> 
> Use of each() on hash after insertion without resetting hash interator
> results in undefined behavior
> 
> Is flooding the logs - I've tried to set "no warnings" or create a copy of
> %transactions and interact with it instead of %transaction itself but no
> luck so far.
> 
> Any ideas?
> 
> Regards,
> 
> Alexandre Andrade | APM Consultant | Ecetera
> alexandre.andrade at ecetera.com.au | M: +61 41307 1370
> 
> Helping rid the World of badly behaving Apps by investigating my Customers
> problems and finding solutions to make things work faster and better.
> Connect to Ecetera on LinkedIn , Twitter
> 
> 
> 
> 
> 
> 
> 
> 
> _______________________________________________
> Melbourne-pm mailing list
> Melbourne-pm at pm.org
> http://mail.pm.org/mailman/listinfo/melbourne-pm


More information about the Melbourne-pm mailing list