in reply to Starting multi-threading

PodMaster is right. You cannot share objects across threads.

The answer may be to create a new instance of the scripting object in each thread. I haven't tried this, so you'll have to suck it and see, but I don't see any reason why it wouldn't work.

As for the free to wrong pool. Do you get these messages when the program closes down?

One note of caution. Multi-threading directory scans, especially if the all (or many of) the paths are on the same physical drive, will have rapidly diminishing returns in terms of performance. Each time a context switch occurs--ie. one thread gets switch for another by the scheduler--then the drive head will have to move to another part of the disk to scan the path for that thread, and then move somewhere else as the next thread takes its turn.

Moving heads between tracks is hugely more expensive than just waiting for the disk to roll passed the head, so the penalty can outweight the benefits. Additionally, reading another part of the disc can cause data already read from the disc into cache but not yet supplied to the program to be invalidated and discarded so that when the program does get around to asking for that information it has to be re-read.

Don't let that put you off trying, but don't be surprised if you find that whilst two or three threads improves performance that 4 starts to diminish it, and 5 really slows things up.

NOTE: Those numbers are just examples. The breakpoint could 6 or 8 or 2. Even just 1, but normally not.


Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
If I understand your problem, I can solve it! Of course, the same can be said for you.

Replies are listed 'Best First'.
Re: Re: Starting multi-threading
by blackadder (Hermit) on Aug 24, 2003 at 19:26 UTC
    ok, this is what I have changed.
    AUTOLOAD; require 5.008; use strict; use warnings 'all'; use diagnostics; use Win32::OLE qw[in]; use threads; use threads::shared; use strict; my @up: shared; my @childs; my $child; my @down: shared; my @list = qw ( c:/winnt d:/perl ); for (@list){ push @childs, threads->create("process_path","$_");} for $child (@childs){ $child->join();} for my $info (@up){ print $info;}#I'll do some work here once I get results sub process_path{ my $path = shift @_; my $Details={}; my $fso = Win32::OLE->new( 'Scripting.FileSystemObject' ); my $FSize = $fso->GetFolder($path); my $Size = $FSize->size(); $Details->{path}=$path; $Details->{size} =$Size; push @up, $Details; }
    and this what iget back in return.
    C:\Scripts>threads1.pl Win32::OLE(0.1403) error 0x800a004c Win32::OLE(0.1403) error 0x800a004c in METHOD/PROPERTYGET "GetFolder" at C:\Scripts\threads1.pl line 3 +3 thread failed to start: Can't call method "size" on an undefined value + at C:\Scripts\threads1.pl line 34 (#1) (F) The entry point function of threads->create() failed for some +reason. in METHOD/PROPERTYGET "GetFolder" at C:\Scripts\threads1.pl line 3 +3 thread failed to start: Can't call method "size" on an undefined value + at C:\Scripts\threads1.pl line 34 (#1) (F) The entry point function of threads->create() failed for some +reason. Free to wrong pool 1a99e90 not 223f58 during global destruction.
    I don't know what else to do to it! So, is this the end?

    Cheers.

      Sorry! Bad guess. I did warn you I hadn't tried it.

      Unfortunately, whilst the scripting object itself and OLE are reentrent, the means of getting to them from perl is not. Any attempt I make to use Win32::OLE from two threads at the same time, even if it is to two different OLE objects, the second one fails.

      I took a quick scan at Win32::OLE but it doesn't look like it would be an easy thing to fix. It was written before threads were around, so reentrancy was never a consideration.

      I had thought that by creating new instances in each thread, which under win32 is pretty much the same as creating different instances in seperate (pseudo-) processes, that it would isolate everything, but it would appear not.

      As I said in the last post, I'm not sure how much you would have gained by threading for this anyway, but unless Win32::OLE gets an update some time soon, I don't see this being easily fixed.


      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
      If I understand your problem, I can solve it! Of course, the same can be said for you.

        Yep, I realise this now, and thanks.

        I was intending to stat more than one shared area on remote server, so my @ARGV parameters would've been something like \\uk_server01\d$\shared_area1, rather than my local hard disk, apologies I should've been more specific here.

        Ok, I am abandoning mission. Thanks again for saving me the hassle:-).