2

毎秒udp経由でローカルポート2222にデータを送信する複数のサーバーからのプロセスがあります。

このデータを読み取って共有メモリに書き込みたいので、他のプロセスが共有メモリからデータを読み取って処理できるようにします。

私は読んでいましたがmmap、ファイルを使用する必要があるようです...理由がわかりません。

a.pyソケットからデータを読み取る がありますが、それを shm に書き込むにはどうすればよいですか?

一度書かれたら、まったく同じshmを読んでそれに対して何かをするために、、、、などb.pyc.py書く必要があります。d.py

コードのヘルプまたはスニペットは非常に役立ちます。

4

2 に答える 2

0

mmapファイル名ではなく、ファイル記述子を取ります。これは、いわゆるメモリ マッピングを実行します。つまり、プロセスの仮想メモリ空​​間内のページを、ファイル記述子によって表されるファイルのようなオブジェクトの部分に関連付けます。これは次のことができるため、非常に強力な操作です。

  • 単純にメモリ内の配列としてファイルのコンテンツにアクセスする。
  • サウンドカードのバッファやグラフィックスアダプタのフレームバッファなど、特殊な I/O ハードウェアのメモリにアクセスする (Unix のファイル記述子は抽象化されており、通常のファイルの代わりにデバイスノードを参照することもできるため、これが可能です)。
  • 同じオブジェクトの共有マップを実行することにより、プロセス間でメモリを共有します。

Unix で共有メモリを使用する POSIX 以前の古い方法は、System V IPC 共有メモリを使用することでした。まず共有メモリ セグメントを で作成しshmget(2)、次に でプロセスにアタッチする必要がありましたshmat(2)。SysV 共有メモリ セグメント (および他の IPC オブジェクト) には名前がなく、むしろ数値 ID があるため、ftok(3)パス名文字列とプロジェクト ID 整数の組み合わせを数値キー ID に変換する特別なハッシュ関数が提供されますが、衝突は発生します。可能。

共有メモリを使用する最新の POSIX の方法は、ファイルのようなメモリ オブジェクトを で開き、 でshm_open(2)目的のサイズにサイズ変更してから、そのサイズに変更ftruncate(2)するmmap(2)ことです。この場合のメモリ マッピングはshmat(2)、SysV IPC API からの呼び出しのように機能shm_open(2)し、初期サイズがゼロのオブジェクトを作成するため、切り捨てが必要です。

(これらは C API の一部です。Python モジュールが提供するのは、多かれ少なかれそれらの呼び出しの薄いラッパーであり、多くの場合、ほとんど同じ署名を持っています)

メモリを共有する必要があるすべてのプロセスで同じ通常ファイルをメモリ マッピングすることで、共有メモリを取得することもできます。実際のところ、Linux は、特別なtmpfsファイル システム上にファイルを作成することにより、POSIX 共有メモリ操作を実装しています。ドライバはtmpfs、ファイルの内容を保持するページを、実行するプロセスのアドレス空間に直接マッピングすることにより、非常に軽量なメモリ マッピングを実装しますmmap(2)。は通常のファイルシステムとして動作するため、やその他のシェル ツールtmpfsを使用してその内容を調べることができます。この方法で共有メモリ オブジェクトを作成したり、既存のオブジェクトの内容を変更したりすることもできます。のファイルの違いlscattmpfs通常のファイルシステム ファイルは、後者がストレージ メディア (ハードディスク、ネットワーク ストレージ、フラッシュ ドライブなど) に永続化され、変更がこのストレージ メディアにフラッシュされることがあり、前者は完全に RAM に保存されます。Solaris も同様の RAM ベースのファイルシステムを提供しており、これは とも呼ばれtmpfsます。

最新のオペレーティング システムでは、メモリ マッピングが広く使用されています。実行可能ファイルは、実行可能コードと静的データを保持するページのコンテンツを提供するためにメモリ マップされます。また、共有ライブラリはメモリ マップされます。これにより、これらのマッピングが共有されるため、物理メモリが節約されます。たとえば、実行可能ファイルまたは共有ライブラリのコンテンツを保持する同じ物理メモリが各プロセスの仮想メモリ空​​間にマップされます。

于 2012-11-22T13:15:54.353 に答える
0

まず、構築しようとしているものには共有メモリ以上のものが必要であることに注意してください:a.py共有メモリに書き込む場合は問題ありませんが、メモリの準備ができて読み取り可能になったことをどのようにb.py知るのでしょうか? 全体として、複数のプロセスを共有メモリ経由ではなく、他のメカニズムを介して接続することで、この問題を解決する方が簡単な場合がよくあります。

mmap(ファイル名が通常必要な理由は、いくつかのプロセスを接続するために名前が必要だからです。実際、両方が を呼び出す場合a.pyb.pyシステムmmap()は、これら 2 つのプロセスがそれらの間でメモリを共有することを求めていることをどのように知るのでしょうか。いくつかの無関係z.py? 両方とも同じファイルを編集したため.ファイルmmap名に対応しない名前を付けるための Linux 固有の拡張子もありますが、それは私見のハックです.)

おそらく、最も基本的な代替メカニズムはパイプです。パイプは通常、プログラムの開始時にシェルの助けを借りて接続されます。これが次の仕組みです (Linux/Unix の場合): python a.py | python b.py. 送信する出力a.pyはパイプに送られ、パイプのもう一方の端は の入力になりb.pyます。a.pyUDPソケットをリッスンしてデータをstdoutに書き込み、b.pystdinから読み取って受信したデータを処理するように記述します。データを複数のプロセスに渡す必要がある場合は、名前付きパイプなどを使用できます。これには、適切な (ただし Bash 固有の) 構文python a.py >(python b.py) >(python c.py)a.pyあります。最初の疑似ファイルに書き込まれたものは何でも、b.py、同様に、2 番目の疑似ファイルに書き込まれた内容は、 の入力として使用されc.pyます。

于 2012-11-21T19:48:32.047 に答える