Почему IPC :: SharedMem игнорирует параметр KEY в конструкторе? - PullRequest
0 голосов
/ 10 августа 2011

Я хочу использовать сегмент совместно используемой памяти для публикации статуса демона Perl, чтобы другие программы в той же системе (ядро Linux 2.6) могли прочитать состояние и сделать простой отчет.

Другие программы должны знать идентификатор общей памяти или KEY для чтения данных из него, поэтому при создании сегмента общей памяти мне нужно выбрать идентификатор (не случайный).

Итак, я сделал простую программу для проверки всего этого и обнаружил здесь нечто странное: хотя я использовал указанный KEY / ID для сегмента общей памяти, когда я печатаю ID общего сегмента, он отличается от того, который я выбрал.

#!/usr/bin/env perl

use 5.012;
use strict;
use IPC::SysV qw/IPC_CREAT/;
use IPC::SharedMem;

# 14614000 is beautifully ignored 
my $shm = IPC::SharedMem->new( 14614000, 8, 00400 | IPC_CREAT );

$shm->write( pack ( 'S', 2 ), 0, 1 );

# Shared memory ID is random
say $shm->id;

getc;

$shm->remove;

Я могу получить доступ к сегменту общей памяти из других программ, только если я использую идентификатор, напечатанный на экране, который я также могу найти с помощью

ipcs -m

Я уверен, что делаю что-то не так, но документация IPC :: SharedMem не помогла выяснить что. Любое предложение?

РЕДАКТИРОВАТЬ: я сделал больше RTFM и понял, что KEY и ID не одно и то же.

Вот "серверная" программа ...

#!/usr/bin/env perl

use 5.012;
use strict;
use IPC::SysV qw/ftok IPC_CREAT IPC_RMID/;

# Make a key: you have to use same parameters of ftok() o refer to this
# shared memory segment.
my $key = ftok( 'ipc_shmem_write.pl', 'A' );

# Create a 16 bytes shared memory segment setting IPC_CREAT
my $id = shmget ( $key, 16, 00644 | IPC_CREAT ) or die "shmget: $!\n";

# Write a 4 octet string to the memory segment starting at offset 0.
shmwrite( $id, 'test', 0, 4 ) or die "shmwrite: $!\n";

# Just wait a key press
getc;

# Destroy shared memory segment, with command IPC_RMID
shmctl( $id, IPC_RMID , 0 ) or die "shmctl: $!\n";

и «клиентская» программа

#!/usr/bin/env perl

use 5.012;
use strict;
use IPC::SysV qw/ftok/;

# Get the same key used by the 'server' program
my $key = ftok( 'ipc_shmem_write.pl', 'A' );

my $status;

# Open the shared memory segment corresponding to KEY $key
my $id = shmget( $key, 16, 0444 ) or die "shmget: $!\n";

# Read 4 octets from shared memory at pos 0 and put in $status
shmread( $id, $status, 0, 4 ) or die "shmread: $!\n";

say $status;

И теперь это работает: программа "client" печатает строку "test".

...