2017-03-02

[Python] POSIX IPCとSystemV IPC

気になったので POSIX IPCSystemV IPC のPythonラッパー的なものをちょっと使ってみました。

結果を淡々と書きます。(キューだけ書き方違うけど許して

POSIX IPC

POSIX IPC リファレンス

インストール

インストールはpipで。

$ pip install posix_ipc Collecting posix_ipc Installing collected packages: posix-ipc Successfully installed posix-ipc-1.0.0

POSIX / メッセージキュー

POSIX メッセージキュー リファレンス

  • プロセス1
  • プロセス2
  • /dev/mqueue
  • import posix_ipc as ipc # mq = ipc.MessageQueue('/test', ipc.O_CREAT) # # # # # mq.send('test') # # mq.send('testtest')
  • import posix_ipc as ipc # mq = ipc.MessageQueue('/test', ipc.O_CREAT) # # # # # # # # # # # mq.receive() (b'test', 0)
  • $ ls /dev/mqueue/ $ ls /dev/mqueue/ test $ cat test QSIZE:0 NOTIFY:0 SIGNO:0 NOTIFY_PID:0 $ cat test QSIZE:4 NOTIFY:0 SIGNO:0 NOTIFY_PID:0 $ cat test QSIZE:12 NOTIFY:0 SIGNO:0 NOTIFY_PID:0 $ cat test QSIZE:8 NOTIFY:0 SIGNO:0 NOTIFY_PID:0

POSIX / 共有メモリ

POSIX IPC 共有メモリ リファレンス

fdが得られるので os.fdopen で開くか mmap を使って操作します。

ここでは mmap を使ってみます。

  • プロセス1
  • プロセス1 stdout
  • プロセス2
  • プロセス2 stdout
  • /dev/shm/
  • import mmap import posix_ipc as ipc s = ipc.SharedMemory('/test_memory', flags=ipc.O_CREAT, size=20, read_only=False) mm = mmap.mmap(s.fd, s.size) mm.write(b'crohaco') # 最終文字を指しているため書き込めない #6 #7 #8 m.seek(0) # 先頭にシークすると書き込めるようになる mm.write(b'crohaco') mm.write(b' suteki') mm.write(b'\n') #13 #14 #15 s.close_fd() mm.write(b'!')
  • #1 #2 #3 #4 Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: data out of range
  • import mmap import posix_ipc as ipc s = ipc.SharedMemory('/test_memory', flags=ipc.O_CREAT, size=20, read_only=False) mm = mmap.mmap(s.fd, s.size) #5 #6 #7 #8 #9 #10 #11 #12 mm.seek(0) mm.read() #15 #16 #17 mm.seek(0) mm.read()
  • #1 #2 #3 #4 #5 #6 #7 #8 #9 #10 #11 #12 #13 b'crohaco suteki\n\x00\x00\x00\x00\x00' #15 #16 #17 #18 b'crohaco suteki\n!\x00\x00\x00\x00'
  • $ ls #2 $ ls test_memory #5 #6 #7 #8 #9 #10 #11 #12 $ cat test_memory crohaco suteki $ rm test_memory $ ls

POSIX / セマフォ

POSIX セマフォ リファレンス

セマフォは共有メモリと同じディレクトリに配置されます

  • プロセス1
  • プロセス1 stdout
  • プロセス2
  • プロセス2 stdout
  • /dev/shm/
  • import posix_ipc as ipc s = ipc.Semaphore('/test_semaphore', flags=ipc.O_CREAT|ipc.O_EXCL, initial_value=2) s.value #4 s.acquire(0) s.value #7 s.acquire(0) #9 #10 #11 s.value s.acquire(0) s.value
  • #1 #2 2 #4 #5 1 #7 Traceback (most recent call last): File "<stdin>", line 1, in <module> posix_ipc.BusyError: Semaphore is busy #11 1 # 0
  • import posix_ipc as ipc #2 s = ipc.Semaphore('/test_semaphore', flags=ipc.O_CREAT, initial_value=2) s.value #5 s.acquire(0) s.value #8 #9 #10 s.release()
  • #1 #2 #3 1 #5 #6 0
  • $ ls sem.test_semaphore

System V IPC

System V IPC リファレンス

インストール

インストールはpipで。

$ pip install sysv_ipc Collecting sysv_ipc Downloading sysv_ipc-0.7.0.tar.gz (93kB) 100% |################################| 102kB 1.9MB/s Installing collected packages: sysv-ipc Running setup.py install for sysv-ipc ... done Successfully installed sysv-ipc-0.7.0

System V / メッセージキュー

System V メッセージキュー リファレンス

  • プロセス1
  • プロセス2
  • ipcs
  • import sysv_ipc as ipc # # # # mq = ipc.MessageQueue(100, ipc.IPC_CREAT) # # # # # mq.send('test') # # # # # mq.send('testtest')
  • import sysv_ipc as ipc # # # # mq = ipc.MessageQueue(100, ipc.IPC_CREAT) # # # # # # # # # # # # # # # # # # mq.receive() # (b'test', 1) # # #
  • $ ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages $ ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages 0x00000064 0 vagrant 600 0 0 $ ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages 0x00000064 0 vagrant 600 4 1 $ ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages 0x00000064 0 vagrant 600 12 2 # # $ ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages 0x00000064 0 vagrant 600 8 1

System V / 共有メモリ

System V 共有メモリ リファレンス

  • プロセス1
  • プロセス1 stdout
  • プロセス2
  • プロセス2 stdout
  • ipcs
  • import sysv_ipc as ipc s = ipc.SharedMemory(100, ipc.IPC_CREAT, size=10) s.read() s.write(b'test') s.read() s.write(b'dayo') # 先頭バイトから上書きされる s.remove() s.write(b'!') s.write(b'!!!!!!!!!!!') # サイズオーバーの書き込みはエラー
  • #1 #2 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' #4 b'test\x00\x00\x00\x00\x00\x00' #6 # # Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: Attempt to write past end of memory segment
  • import sysv_ipc as ipc s = ipc.SharedMemory(100, ipc.IPC_CREAT, size=10) s.read() # s.read() # s.read() # s.read() #
  • # # b'' # b'test\x00\x00\x00\x00\x00\x00' # b'dayo\x00\x00\x00\x00\x00\x00' # b'!ayo\x00\x00\x00\x00\x00\x00'
  • # $ ipcs -m ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x00000000 131072 vagrant 600 10 2 dest

System V / セマフォ

System V セマフォ リファレンス

  • プロセス1
  • プロセス1 stdout
  • プロセス2
  • プロセス2 stdout
  • ipcs
  • import sysv_ipc as ipc s = ipc.Semaphore(100, ipc.IPC_CREAT, initial_value=2) s.value s.acquire(0) s.value #6 #7 s.acquire(0) #9 #10 #11 s.value s.acquire(0) s.value
  • #1 #2 2 #4 1 #6 #7 Traceback (most recent call last): File "<stdin>", line 1, in <module> sysv_ipc.BusyError: The semaphore is busy #11 1 #13 0
  • import sysv_ipc as ipc #2 s = ipc.Semaphore(100) # ipc.IPC_CREATつけると上書きされちゃう #4 s.value s.acquire(0) s.value #9 #10 #11 s.release()
  • #1 #2 #3 #4 1 #6 0
  • # # $ ipcs -s ------ Semaphore Arrays -------- key semid owner perms nsems 0x00000064 98304 vagrant 600 1

参考

POSIX Message Queueのキューをepollで取得Linux 環境では Posix Message Queue は仮想ファイルシステム上に作成するよう実装されており、mq_open(3) が返すメッセージ・キューディスクリプタはファイルディスクリプタでもある。 On Linux, message queues are created in a virtual file system. 実際にキューを取得待ち状態にし lsof を実行すると、…https://siguniang.wordpress.com/2012/09/28/receive-posix-message-queue-with-epoll/ SysV IPC:Message Queueいま保守担当しているシステムの一つで SysV IPC のメッセージキューというのを利用してプロセス間通信しているのを発見したため、どんなものなのかさわってみた。 メッセージキューの概要/使い方 次の解説記事を参考にした。 Share application data with UNIX System V IPC mechanisms @ DeveloperWorks Beej’…https://siguniang.wordpress.com/2009/11/07/sysv-ipcmessage-queue/