in reply to Problem in Inter Process Communication

It would be much easier to help you if you would post the code you have.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."
  • Comment on Re: Problem in Inter Process Communication

Replies are listed 'Best First'.
Re^2: Problem in Inter Process Communication
by libvenus (Sexton) on Aug 20, 2008 at 10:30 UTC
    use strict; use threads; use threads::shared; use Thread::Semaphore; use POSIX; my @clientList = qw(client1 client2 client3 client4 client5 client6 cl +ient7 client8 client9 client10 client11 client12); my @dmServers = qw +(A B C); my @queryPath = qw(AA BB CC DD EE FF); my @shared; my $query +Index = 0; my $maxnoofThreads = 2; my %sharedHash : shared; for (my $i = 0;$i < @dmServers;$i++) { my $cpid = fork(); die unless defined $cpid; if (! $cpid) { # This is the child # my $wait = int rand 10; # sleep $wait; callChild($queryPath[$queryIndex++],$dmServers[$i +],$i); #print "Child $$ exiting after seconds\n"; exit; } } # Just parent code, after this while ((my $cpid = wait()) != -1) { #print "Waited for child $cpid\n"; #print " length of array shared",length(@shared); } #print "Parent Exiting\n"; sub callChild { my $query = shift; my $dmserver = shift; my $i = shift; #print " query fired $query on dmserver $dmserver index $i\n"; my @clientList_temp = @clientList; for(my $index = $i; $index < @queryPath;$index = $index + @dmS +ervers) { print "process $$ query at $index is ",$queryPath[$i +ndex],"\n"; # $shared[$i] = $i; # sleep rand(10); for(my $a;$a <= $maxnoofThreads;$a++) { my $sema = Thread::Semaphore->new(); my @temp = splice(@clientList_temp,0,ceil(@clientL +ist/$maxnoofThreads)); my $thr = thread->new(\&worker,$sema,\@temp,$query +Path[$index]); #if( defined %sharedHash) # { # my $thrnew = thread->new(\&compare); # $sema->up; # } } foreach my $thr (threads->list) { # Don't join the main thread or ourselves if ($thr->tid && !threads::equal($thr, th +reads->self)) { ##########Not Sure ####### foreach my $client ( +keys %sharedHash) { print " client $client\n"; my $thrnew = thread->new(\&compar +e,$client); $sema->up; } $thr->join; } } } #$shared[$i] = undef; } sub worker { my $sema = shift; my $myClientArrayRef = shift; my $query = shift; for(my $i;$i < @$myClientArrayRef;$i++) { print " $$myClientArrayRef[$i] client \n"; sleep 5; my $thrid = threads->tid; $sharedHash{$$myClientArrayRef[$i]} = $thrid; shift @$myClientArrayRef; $sema->down; } } sub compare { my $client = shift; print " hash value ",$sharedHash{$client},"\n"; }

      Okay, I guess the question I have is, why do you need to fork before creating threads? Are you running this on win32? some nix flavor? If its win32, then the threads and actually forks, and using threads aren't really saving you much of anything

      Note, in the code you've posted, you have a scope problem:
      if ( $thr->tid && !threads::equal( $thr, th +reads->self ) + ) { ##########Not Sure ####### foreach my $client ( keys %sharedHash ) { print " client $client\n"; my $thrnew = thread->new( \&compare, $client ); $sema->up; }

      $sema is not defined in this context, its local to the previous loop. there are numerous other bugs, but i'll leave that to you to find ;)

      Again, I would refer you the the thread primer http://perlmonks.org/?node_id=691785 and the like http://perlmonks.org/?node_id=704138, but I've made a stab at doing what I _think_ you are looking to have done

      Note that the control structure of what I've done is _extremely_ sloppy and I would not reccommend it.

      note that i don't quite understand why you need to thread your compares, but, I guess if that is also a time consuming operation, it could make sense

      also note that I made your worker sub and compare sub local to the sub that is running in the fork. I did this for my own readability, as well as to remind myself that they are really running in the scope of the forked process and not the main program

      In that vein, in my shared hash, I did not need the pid as a key in the hash, I just put it there for clarity, each forked process will be local unto itself, only copying the values, etc that are available at the time the process is forked (at least the way I understand the world

      anyhow, hope this is helpful

        Hi JoeKamel Thanks a ton for your help !!!

        >>> why do you need to fork before creating threads ?

        Well the kind of model that i have thought off is that the application starts , based on the no of children i can fork( the app starter defines it based on the server load), i fork that many children. Each child notes the index of the query that has been passed to it by the parent and increments it with the total no of children spawned to come to its batch of next query.Each child now has to do the following tasks : pick the query + build ( replace client placeholders with real values) + fire to prod/test and then compare the results(time taking)

        So each child constructs 3 threads ( user defined) and divides the client array into 3 equal parts and distributes to each, along with the query that they must build(replace client placeholders with real values) and fire.Now each thread is looping on the total no of client s(1/3 of the total).In each loop it builds the query , fires it and stores the results in some Data structure and lets its main process know that it has got the result of one query+client , then supsends itself( if i do not suspend the thread all the results would slurp in the memory). The main process now knows that it has some result on which either it can work on or launch a new thread to work parallely and not block until the comparison finshes. In each comparison thread if some differences are found in prod and test results they are appended to a file and the memory deallocated.

        >>>>Are you running this on win32? some nix flavor?

        linux

        >>>>Note, in the code you've posted, you have a scope problem

        yeah i know , i was trying to do the suspend/resume via semaphore and i didn't succeed. :-((

        >>>>note that i don't quite understand why you need to thread your compares

        i guess i have answered that above

      Take a look at mutexes in perl e.g. APR::ThreadMutex or Threads::Shared

      If you need to share data between threads then the principle is to mutually exclude all other threads from modifying that data while you transfer it.

      Just set up a mutual exclusion and be religious about gaining and releasing it. You may not need to gain and release in the same subroutine.