(WinXP SP2, AS5.8.6) I'm trying to build an strace for Perl scripts (as described in Perl coredump analysis tool ?) using memory mapped files, as its about the only reasonably similar shared memory mechanism between Win32 and *nix. I'm using Win32::MMF::Shareable for Win32, and Sys::Mmap for *nix platforms.

In order to keep most of the mmf access identical between Win32 and *nix, I'm using a single tied scalar string for Win32::MMF, and then applying substr() operations to read/write to it (as is used by Sys::Mmap).

I have successfully run a single threaded app and monitored it via a completely separate app.

Unfortunately, Win32::MMF::Shareable seems to be misbehaving with concurrent threaded access to the memory mapped file. I've reviewed Perl forking and shared memory strangeness under Windows, and applied its recommended fix (ie, re-require'ing MMF and retying in the child threads), but I'm seeing an apparent latency issue where the tie doesn't seem to pick up the right piece of the MMF if concurrent accesses are made close to each other, ie,

  1. The mmf is inited to all zeroes.
  2. Thread 1 writes an integer 1 at byte 100 of the mmf
  3. Thread 2 reads an integer at byte 500 of the mmf, expecting to get zero, but gets the value of 1 written by thread 1

The instances where this occurs seems somewhat random, and often injecting a few seconds wait time between operations improves the behavior.

And in the process of trying to write a small script to illustrate the issue, I've encountered another problem: the allocated size of the mmf isn't being properly setup in the threads (see below, where each thread prints out its notion of the length of the tied scalar), resulting in "substr outside of string" failures when there shouldn't be any.

Is there a known problem with Win32 memory mapped files, or is this an issue with Win32::MMF::Shareable ?

The code...

use threads; use threads::shared; use Win32::MMF::Shareable; use strict; use warnings; # # main thread creates the mmf # my $mmf; tie $mmf, 'Win32::MMF::Shareable', 'mmf', { namespace => 'Win32MMFTest', size => 10000, reuse => 0 }; # # and inits it # $mmf = 'A' x 10000; # # start each thread to run concurrent tests # my $locker : shared = 0; # # add a lock for the mmf - even tho !!!we shouldn't need it!!! # my $mmflock : shared = 0; my $thrd1 = threads->create(\&runtest, 0); my $thrd2 = threads->create(\&runtest, 5000); my @tids = ($thrd1->tid, $thrd2->tid); # # signal to run # { lock($locker); $locker = 1; cond_broadcast($locker); } # # and wait for completion # { lock($locker); cond_wait($locker) while ($locker < 3); } # # read back each thread's modifications # foreach my $i (0..19) { foreach (0..$#tids) { my ($first, $second, $third) = unpack('l d S/a*', substr($mmf, (5000 * $_) + ($i * 200), +200)); print "$first $second $third\n"; print STDERR "wires got crossed!!!\n" unless ($first == $tids[$_]); } } $thrd1->join(); $thrd2->join(); sub runtest { my $region = shift; # # wait for signal to run # my $tid = threads->self->tid; { lock($locker); cond_wait($locker) while ($locker < 1); } # # maybe we need to re-require for Win32::MMF::Shareable in a new # thread or process ? # (see http://www.perlmonks.com/?node_id=331029) # require Win32::MMF::Shareable; my $mmf; tie $mmf, 'Win32::MMF::Shareable', 'mmf', { namespace => 'Win32MMFTest', size => 10000, reuse => 1 }; print "length of mmf is ", length($mmf), "\n"; # # write some stuff to our region # foreach (0..15) { print "$tid at ", $region + ($_ * 200), "\n"; my $entry = "this is the $region region for tid $tid"; my $len = length($entry); # # why does this die ???? # eval { lock($mmflock); # realy shouldn't be needed! substr($mmf, $region + ($_ * 200), $len + 14) = pack('l d S a*', $tid, time(), $len, $entry); }; print "Failure in $tid at ", $region + ($_ * 200), "\n" and la +st if $@; } # # signal completion # { lock($locker); $locker++; cond_broadcast($locker); } return 1; }

In reply to Win32::MMF + threads misbehavior by renodino

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.