in reply to IPC::Msg - determine if queue is full

The last time I played with it, I found it quite cumbersome to handle shared memory; mostly because of all the hex notation, dealing with lengths of variables in c terms, etc. You have to keep track of what portion of the shared memory corresponds to which of you variables, AND you have to make sure you don't get extraneous hex junk appended. Like I said, it was too cumbersome for my tastes.

Here is an example set of scripts that may show you whats up, I hope they help. :-)

#!/usr/bin/perl # this is the init script use warnings; use strict; use IPC::SysV qw(IPC_STAT IPC_PRIVATE IPC_CREAT IPC_EXCL S_IRUSR S_IWU +SR IPC_RMID S_IRWXU); use IPC::Msg; # see "perldoc perlfunc /shmget" and "perldoc perlipc /SysV" # big difference from c is attach and detach is automatic in Perl # it attaches to read or write, then detaches my $IPC_KEY = 1234; my $msg = new IPC::Msg($IPC_KEY, S_IRWXU | IPC_CREAT); my $go = 1; $SIG{INT} = sub{ $go = 0; &close_m(); #close up the shared mem exit; }; my $segment_hbytes = 0x640; # hex bytes, a multiple of 4k my ($segment_id, $segment_size) = &init_m($segment_hbytes); print "shmid-> $segment_id\tsize-> $segment_size\n"; # put the shmid on the message queue # 1 message for each client to connect # since each read shifts one off my $msgout = $segment_id; my $numclients = 3; for(1..$numclients){ $msg->snd(1, $msgout, 0 ); } #check it ( will reduce the number of msgs available #my $msgin = ''; #$msg->rcv($msgin, 8 ,0); # 8 bytes for a Perl integer #print "msgin->$msgin\n"; #$msg->rcv($msgin, 8 ,0); # 8 bytes for a Perl integer #print "msgin1->$msgin\n"; my $i = 'a'; while($go){ &write_m($i); $i++; select(undef,undef,undef,.1); last if ! $go; } exit; ################################################################# sub init_m(){ my $segment_hbytes = shift; # Allocate a shared memory segment. my $segment_id = shmget (IPC_PRIVATE, $segment_hbytes, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR); # Verify the segment's size. my $shmbuffer = ''; shmctl ($segment_id, IPC_STAT, $shmbuffer); my @mdata = unpack("i*",$shmbuffer); return($segment_id, $mdata[9] ); } sub write_m() { # Write a string to the shared memory segment. my $message = shift; shmwrite($segment_id, $message, 0, $segment_size) || die "$!"; return 0; } sub close_m(){ # Deallocate the shared memory segment. shmctl ($segment_id, IPC_RMID, 0); $msg->remove; return 0; } __END__

####### and this is the listener ##########################

#!/usr/bin/perl # this script will take data from shmem use warnings; use strict; use IPC::SysV qw(IPC_STAT IPC_NOWAIT); use IPC::Msg; #see "perldoc perlfunc /shmget" and "perldoc perlipc /SysV" my $IPC_KEY = 1234; my $msg = new IPC::Msg($IPC_KEY,0); #my $msg = new IPC::Msg($IPC_KEY, 1); print "msg->$msg\n"; my $go = 1; #get shmid from msg my $segment_id; $msg->rcv($segment_id, 8 , 0); # 8 bytes for a Perl integer print "shmid->$segment_id\n"; $SIG{INT} = sub{ $go = 0; exit;}; my $segment_size = &size_m($segment_id); print "segment_size = $segment_size\n"; while($go){ my $readm = &read_m(); print "$readm\n"; last if ! $go; select(undef,undef,undef,.1); } ############################################################# sub size_m(){ my $segment_id = shift; my $shmbuffer = ''; shmctl ($segment_id, IPC_STAT, $shmbuffer); my @mdata = unpack("i*",$shmbuffer); #not sure if that is right unp +ack? works :-) print "segment size: ", $mdata[9], "\n"; return($mdata[9]); } #################################################################3 sub read_m(){ my $buff; #the $buff is paaded with nulls \0 to fill it out shmread($segment_id, $buff, 0, $segment_size) || die "$!"; # the buffer of shmread is zero-character end-padded. #substr($buff, index($buff, "\0")) = ''; return ($buff); } __END__

I'm not really a human, but I play one on earth. flash japh