忍者ブログ
ロボット、千葉ロッテマリーンズについていいかげんなことを書きます。
[1]  [2]  [3]  [4
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

どうにも共有メモリについて根本的な勘違いをしていたみたいなのでメモしておきます。
間違ったことを書いている可能性が高いので、気づいたら指摘してください。


まずWindowsでCreateFileMappingやMapViewOfFileを使用してプロセス間通信を実装すると、ファイルを介して情報をやりとりするという事になるようです。
どこかにファイルを作成して、そのファイルの内容を実行しているプロセスの仮想アドレスにマッピングする事であたかもメモリのように操作できるという事らしいです。
このサイトの図2のようなイメージです。


WIndowsでは以下のソースコードです。

HANDLE fh=CreateFile("MapFile",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL);
HANDLE hMap = CreateFileMapping(fh , NULL , PAGE_READWRITE , 0 , 4 , NULL);
void* pshared = MapViewOfFile( hMap, FILE_MAP_ALL_ACCESS, 0, 0, 4 );
reinterpret_cast<int*>(pshared)[0] = 100;
UnmapViewOfFile( pshared );
CloseHandle( hMap );
CloseHandle(fh);


ちなみにCreateFileMappingの引数を変更すると仮想メモリに領域を確保
するようにできるらしいです。

HANDLE hMap = CreateFileMapping((HANDLE)0xFFFFFFFF , NULL , PAGE_READWRITE , 0 , 4 , ”MapFile”);

こうすればファイルの正確な場所が分からなくても空間名さえ分かっていればアクセスできるという事になります。



Linuxでは以下のソースコードに対応すると思います。

const int fd=open("MapFile",O_RDWR|O_CREAT,0666)
int *ptr=(int *)mmap(0,4,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
ptr[0] = 100;
munmap(ptr,4);
close(fd);




Pythonではmmapというライブラリで実装できます。

f = open('MapFile', 'r+')
m = mmap.mmap(f.fileno(), 4)
value = struct.pack("i",100)
m.write(value)
m.close()
f.close()


Windowsの場合、ファイルハンドルに0と空間名を与えると上と同じく仮想メモリに領域を確保するみたいです。

shmem = mmap.mmap(0, 4, 'MapFile')


結局のところハードディスク上のファイルを介して他のプロセスと情報のやり取りを行うので、通信速度は遅いように思えますが、それでもソケット通信等に比べれば圧倒的に速いみたいです。自分の環境で比較しただけなので確実な事は言えませんけど。





ここまではファイルの内容をマッピングする方法ですが、以下の方法もあるようです。

まずWindowsではReadProcessMemory関数、WriteProcessMemory関数を使用する事で他のプロセスの仮想アドレスに直接アクセスできるらしいです。



Linuxではshm_open関数、shmget関数等で共有メモリが使えるらしいです。
この場合、ファイルは/dev/shm以下に作成されます。この/dev/shmはディスク上ではなくメモリにマウントされているので高速な通信ができるらしいです。

つまりshm_open関数で/dev/shm/MapFIleを作成すると、一見ディスク上にファイルが作成されたように見えますが実はメモリ上で操作しているという事になります。

そして作成した/dev/shm/MapFIleを上と同じくmmapで仮想アドレスにマッピングすると、共有メモリとして扱えるようになります。


 



・・・・・ということで合っていますでしょうか?


ちなみに以下のコードで実装できます。

const int fd = shm_open( 'MapFile', O_RDWR|O_CREAT, 0 );
ftruncate( fd , 4);
void* ptr = mmap( NULL, 4, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0 );
ptr[0] = 100;
munmap(ptr,4);
close( fd );
shm_unlink( 'MapFile' );


見て分かる通り、mmapの引数に入れるファイルディスクリプタを変更するだけです。



Pythonの場合は以下のコードで実装できます。


try:
rt = ctypes.CDLL('librt.so')
except:
rt = ctypes.CDLL('librt.so.1')


rt.shm_open.argtypes = [ctypes.c_char_p, ctypes.c_int, ctypes.c_int]
rt.shm_open.restype = ctypes.c_int
rt.ftruncate.argtypes = [ctypes.c_int, ctypes.c_int]
rt.ftruncate.restype = ctypes.c_int
rt.close.argtypes = [ctypes.c_int]
rt.close.restype = ctypes.c_int
rt.shm_unlink.argtypes = [ctypes.c_char_p]
rt.shm_unlink.restype = ctypes.c_int


O_RDONLY = 0
O_WRONLY = 1
O_RDWR = 2
O_CREAT = 64


fd = rt.shm_open('MapFile',O_RDWR | O_CREAT ,0)
rt.ftruncate(fd, 4)
m= mmap.mmap(fd, 4, mmap.MAP_SHARED)
value = struct.pack("i",100)
m.write(value)
m.close()
rt.close( fd )
rt.shm_unlink('MapFile')















PR





ヘビ型ロボットの操作インターフェースです。

・・・というより、さっき1時間ぐらいで作ったから何もできてません。


これを配布しても意味は特になさそうな感じが漂いまくってるので、どうしようかな・・・

とりあえずここで配布はしないので、馬研の人で欲しい人は僕に直接言ってください。









ランキングに参加してます。押していただけると今まで経験がないくらい嬉しいです。
にほんブログ村 IT技術ブログ Pythonへ
にほんブログ村の
Pythonのカテゴリ
現在参加人数7人・・・
人気ブログランキングへ   
いつのまにか,にほんブログ村のPythonのカテゴリーの参加人数が7人に増えてますね.

数ヶ月前までは僕1人だったのに.


ようやく,みんなPythonの素晴らしさに気付き始めたってことでしょう.誇張しすぎ




それから,お知らせです.

ちょっと前の記事で,ヒューマンインタフェースシンポジウムの感想を書くと言いましたが・・・

忙しいのでやめときます.

講演会に参加するのも,タダじゃないですしね.








ここまでの話とは全く,一切関係ない話ですが・・・

昨日のHISAOのヒットで,ものすごいテンションが上がりました.


どうせ得点に繋がらんだろうと思ってたら,

案の定,小谷野のファインプレーでゲッツーとなりました.


予定調和すぎる・・・








ランキングに参加してます。押していただけると今まで経験がないくらい嬉しいです。
にほんブログ村 IT技術ブログ Pythonへ
にほんブログ村の
Pythonのカテゴリ
現在参加人数7人・・・
人気ブログランキングへ   

今回はPyQtとRTミドルウェアによりグラフを複数表示するコンポーネントを作りました。

サンプルを置くページからQtGraphComp.zipをダウンロードしてください。






手抜き動画ですが大体の概要はわかる・・・と思うよ?

手順は、
 

  1. QtGraph.pywを実行
  2. 赤い丸で囲ったスピンボックスの値を変えてグラフを好きなだけ作成
  3. 青い丸で囲ったコンボボックスでそれぞれのグラフにデータの型を設定
  4. 緑の丸で囲ったCreateボタンでコンポーネント作成
  5. 接続してアクティブにする



今のところ対応してるデータの型は、
 

  • TimedLong
  • TimedLongSeq
  • TimedDouble
  • TimedDoubleSeq
  • TimedFloat
  • TimedFloatSeq

です。


なお、Rangeは横軸の幅、HIGHは縦軸の最大値、LOWは横軸の最大値を指定できます。

ただし、FIXというところがFixに設定されてないとHIGHとLOWは意味がありません。

Freeはサンプリングしたデータの最大値、最小値に応じてグラフの縦軸の最大値、最小値が変動します。

対して、Fixだと固定されます。



こんなところかな。






 








 

ランキングに参加してます。押していただけると今まで経験がないくらい嬉しいです。
にほんブログ村 IT技術ブログ Pythonへ
にほんブログ村の
Pythonのカテゴリ
現在参加人数1人・・・
人気ブログランキングへ   

その4でPyQtで作ったGUIをRTコンポーネント化した際、グローバル変数を使いましたがOpenRTM-aist-Python-1.0.0のサンプルではもっときれいな方法でやってます。

今回はその4でのプログラムを少し書きなおしました。

サンプルはサンプルを置くページからPyQt-SAMPLE4-2.zipをダウンロードしてください。

手順としては、
 

  1. Dialogクラスの set_on_update(self, func) で self.on_update に関数funcを入れるようにする。
  2. GuiControllerクラスの set_out(self, b1, b2) のようにb1、b2をself.OUTに入れる関数を作る。
  3. self.OUT をアウトポートから出力するようにする。(onExecute)
  4. main で dialog.set_on_update(comp.set_out) のように関数set_outをset_on_updateのfuncにする。
  5. RTCBuilderの作るコードでは comp = mgr.createComponent("GuiController") がmainでは扱えず、dialog.set_on_update(comp.set_out) のようにset_out関数が使えないためサンプルのようにmain内に書きなおす。


こんな所。

全部同じファイルに書くならグローバル変数のほうが良いと思います。















ランキングに参加してます。押していただけると今まで経験がないくらい嬉しいです。
にほんブログ村 IT技術ブログ Pythonへ
にほんブログ村の
Pythonのカテゴリ
現在参加人数1人・・・
人気ブログランキングへ   

カレンダー
03 2024/04 05
S M T W T F S
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
フリーエリア
最新CM
[08/31 ysuga]
[08/31 Nobu]
[08/31 ysuga]
[12/11 Nobu]
[12/11 Kanamura]
最新TB
プロフィール
HN:
Nobu
年齢:
35
性別:
男性
誕生日:
1988/09/22
職業:
あれ
趣味:
妄想、自堕落
バーコード
ブログ内検索
P R
カウンター
忍者ブログ [PR]