Main Content

アプリケーション間でのメモリの共有

この例では、共有ファイルに対する書き込みと読み取りによって情報を交換する 2 つの独立した MATLAB® プロセスを実装する方法を説明します。この両方のプロセスでは、メモリ空間の一部をファイル内の共通の場所に対しマッピングすることによってファイルが共有されます。第 1 のプロセスに属するメモリ マップへの書き込み操作は、第 2 のプロセスに属するマップから読み取ることができ、その逆も可能です。

1 つの MATLAB プロセス (send.m の実行) によって、メモリ マップを介してファイルにメッセージが書き込まれます。このプロセスではまた、メッセージの長さがファイルの第 1 バイトに書き込まれ、これはメッセージが利用可能であることをもう一方のプロセスに知らせる方法となります。第 2 のプロセス (answer.m の実行) では第 1 バイトをモニターし、その設定が確認されると受け取ったメッセージを表示し、それを大文字にして送信側にメッセージを送り返します。

この例を実行する前に、関数 send および answer を、現在の作業ディレクトリ内のファイル send.m および answer.m にコピーします。

関数 send

この関数はテキストの入力を求め、メモリ マッピングを使用して、そのテキストを関数 answer を実行している MATLAB のもう 1 つのインスタンスに渡します。

function send
% Interactively send a message to ANSWER using memmapfile class.
 
filename = fullfile(tempdir, 'talk_answer.dat');
 
% Create the communications file if it is not already there.
if ~exist(filename, 'file')
    [f, msg] = fopen(filename, 'wb');
    if f ~= -1
        fwrite(f, zeros(1,256), 'uint8');
        fclose(f);
    else
        error('MATLAB:demo:send:cannotOpenFile', ...
              'Cannot open file "%s": %s.', filename, msg);
    end
end
 
% Memory map the file.
m = memmapfile(filename, 'Writable', true, 'Format', 'uint8');
 
while true
    % Set first byte to zero, indicating a message is not
    % yet ready.
    m.Data(1) = 0;
 
    str = input('Enter text (or RETURN to end): ', 's');
 
    len = length(str);
    if (len == 0)
        disp('Terminating SEND function.')
        break;
    end
    
    % Warn if the message is longer than 255 characters.
    if len > 255
        warning('ml:ml','SEND input will be truncated to 255 characters.');
    end
    str = str(1:min(len,255));  % Limit message to 255 characters.
    len = length(str); % Update len if str has been truncated. 
    
    % Update the file via the memory map.
    m.Data(2:len+1) = str;
    m.Data(1)=len;
   
 
    % Wait until the first byte is set back to zero, 
    % indicating that a response is available.
    while (m.Data(1) ~= 0)
        pause(.25);
    end
    
    % Display the response.
    disp('response from ANSWER is:')
    disp(char(m.Data(2:len+1))')
   
end

関数 answer

関数 answer では、メモリ マッピングを使用して、send からのメッセージを監視するサーバーを起動します。メッセージを受け取ると、answer によってメッセージは大文字のバージョンに置き換えられ、この新しいメッセージが send に送り返されます。answer を使用するには、入力引数なしで呼び出します。

function answer
% Respond to SEND using memmapfile class.

disp('ANSWER server is awaiting message');

filename = fullfile(tempdir, 'talk_answer.dat');

% Create the communications file if it is not already there.
if ~exist(filename, 'file')
    [f, msg] = fopen(filename, 'wb');
    if f ~= -1
        fwrite(f, zeros(1,256), 'uint8');
        fclose(f);
    else
        error('MATLAB:demo:answer:cannotOpenFile', ...
              'Cannot open file "%s": %s.', filename, msg);
    end
end

% Memory map the file.
m = memmapfile(filename, 'Writable', true, 'Format', 'uint8');

while true
    % Wait until the first byte is not zero.
    while m.Data(1) == 0
        pause(.25);
    end
    
    % The first byte now contains the length of the message.
    % Get it from m.
    msg = char(m.Data(2:1+double(m.Data(1))))';

    % Display the message.
    disp('Received message from SEND:')
    disp(msg)
    
    % Transform the message to all uppercase.
    m.Data(2:1+double(m.Data(1))) = upper(msg);
   
    % Signal to SEND that the response is ready.
    m.Data(1) = 0;
end

例の実行

実行時の例がどのようになるかを確認するために、1 つのコンピューターで 2 つ別々の MATLAB セッションを開始します。一方の MATLAB セッションで、入力引数を指定せずに関数 send を呼び出します。もう一方のセッションで関数 answer を呼び出し、共通のファイルへのマップを各プロセスのメモリに作成します。

最初の MATLAB セッションで send を実行します。

send
Enter text (or RETURN to end):

2 番目の MATLAB セッションで answer を実行します。

answer
ANSWER server is awaiting message

次に、関数 send によって表示されるプロンプトでメッセージを入力します。メッセージは MATLAB によって共有ファイルに書き込まれます。関数 answer を実行している 2 番目の MATLAB セッションでは共有ファイルの第 1 バイトをループによって監視し、このバイトが send によって書き込まれると、answer ではメモリ マップを介してファイルからメッセージが読み取られます。次に、関数 answer によってメッセージが大文字に変換されてファイルに書き戻され、(応答待ちとなっていた) send によってこのメッセージが読み取られて表示されます。

send によりメッセージが書き込まれ、大文字の応答が読み取られます。

Hello. Is there anybody out there?
response from ANSWER is:
HELLO. IS THERE ANYBODY OUT THERE?
Enter text (or RETURN to end): 

answer により send からのメッセージが読み取られます。

Received message from SEND:
Hello.  Is there anybody out there?

関数 send によって表示されるプロンプトに 2 番目のメッセージを入力します。このメッセージは send によってファイルに書き込まれます。

I received your reply.
response from ANSWER is:
I RECEIVED YOUR REPLY.
Enter text (or RETURN to end):

answer によって 2 番目のメッセージが読み取られ、大文字に変換されてからファイルに書き込まれます。

Received message from SEND:
I received your reply.

MATLAB の最初のインスタンスで Enter キーを押して例を終了します。

Terminating SEND function.