前天介绍了linux进程间通信──消息队列,由于消息队列是linux内核提供的功能,所以理所当然地,C语言用起来最为方便:直接include一个sys/msg.h就可以了,所以之前的文章,我也是用C语言来做演示的.
那么我喜欢的Python能不能用IPC呢?能不能像C一样用消息队列呢?
其实,Python的内置模块里,并没有对IPC的支持,但是好在python的可扩展性超强,我们可以用swig来为python增加一个IPC模块.方法如下:
下载这个tar包(修改自这里),解压到任意目录,得到 ipc.h ipc.i Makefile 3个文件,如果你不是用的python2.6,需要修改一下 Makefile 里的路径(python3系列未测试).然后
make && make install
make && make install
这样,你就可以在python里 import ipc模块了.
还是贴示例代码,保存为ipc_msg.py,并加可执行权限:
#!/usr/bin/env python
import sys,ipc
if len(sys.argv)==5 and sys.argv[3][0]=='s':
ipc_key=int(sys.argv[1])
msg_id = ipc.msgget(ipc_key,0666|ipc.IPC_CREAT)
if 0 > msg_id:
sys.exit(1)
mbuf = ipc.msgbuf()
mbuf.mtype = int(sys.argv[2])
mbuf.mtext = sys.argv[4]
if 0 > ipc.msgsnd(msg_id,mbuf,len(mbuf.mtext),0):
sys.exit(3)
print 'Send Success.'
elif len(sys.argv)==4 and sys.argv[3][0]=='r':
ipc_key=int(sys.argv[1])
mbuf = ipc.msgbuf()
msg_id = ipc.msgget(ipc_key,0666)
if 0 > msg_id:
sys.exit(1)
msg_len=ipc.msgrcv(msg_id,mbuf,2048,int(sys.argv[2]),ipc.IPC_NOWAIT)
if 0 > msg_len:
print 'No message received.'
sys.exit(3)
else:
print 'Recv Success.(%d bytes):'% msg_len
print mbuf.mtext
elif len(sys.argv)==3 and sys.argv[2][0]=='c':
ipc_key=int(sys.argv[1])
id_dsp = ipc.msqid_ds()
msg_id = ipc.msgget(ipc_key,0666)
if 0 > msg_id:
sys.exit(1)
if 0 > ipc.msgctl(msg_id,ipc.IPC_RMID,id_dsp):
sys.exit(2)
else:
print "usage: \n%s key type s message --to send message\n\
%s key type r --to receive\n\
%s key c --to clear queue"\
%(sys.argv[0],sys.argv[0],sys.argv[0])
#!/usr/bin/env python
import sys,ipc
if len(sys.argv)==5 and sys.argv[3][0]=='s':
ipc_key=int(sys.argv[1])
msg_id = ipc.msgget(ipc_key,0666|ipc.IPC_CREAT)
if 0 > msg_id:
sys.exit(1)
mbuf = ipc.msgbuf()
mbuf.mtype = int(sys.argv[2])
mbuf.mtext = sys.argv[4]
if 0 > ipc.msgsnd(msg_id,mbuf,len(mbuf.mtext),0):
sys.exit(3)
print 'Send Success.'
elif len(sys.argv)==4 and sys.argv[3][0]=='r':
ipc_key=int(sys.argv[1])
mbuf = ipc.msgbuf()
msg_id = ipc.msgget(ipc_key,0666)
if 0 > msg_id:
sys.exit(1)
msg_len=ipc.msgrcv(msg_id,mbuf,2048,int(sys.argv[2]),ipc.IPC_NOWAIT)
if 0 > msg_len:
print 'No message received.'
sys.exit(3)
else:
print 'Recv Success.(%d bytes):'% msg_len
print mbuf.mtext
elif len(sys.argv)==3 and sys.argv[2][0]=='c':
ipc_key=int(sys.argv[1])
id_dsp = ipc.msqid_ds()
msg_id = ipc.msgget(ipc_key,0666)
if 0 > msg_id:
sys.exit(1)
if 0 > ipc.msgctl(msg_id,ipc.IPC_RMID,id_dsp):
sys.exit(2)
else:
print "usage: \n%s key type s message --to send message\n\
%s key type r --to receive\n\
%s key c --to clear queue"\
%(sys.argv[0],sys.argv[0],sys.argv[0])
运行结果:
lily@LLY:~/test/ipc$ ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
lily@LLY:~/test/ipc$ ./ipc_msg.py 1 2 s abc
Send Success.
lily@LLY:~/test/ipc$ ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
0x00000001 65536 lily 666 3 1
lily@LLY:~/test/ipc$ ./ipc_msg.py 1 2 r
Recv Success.(3 bytes):
abc
lily@LLY:~/test/ipc$ ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
0x00000001 65536 lily 666 0 0
lily@LLY:~/test/ipc$ ./ipc_msg.py 1 c
lily@LLY:~/test/ipc$ ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
lily@LLY:~/test/ipc$
lily@LLY:~/test/ipc$ ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
lily@LLY:~/test/ipc$ ./ipc_msg.py 1 2 s abc
Send Success.
lily@LLY:~/test/ipc$ ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
0x00000001 65536 lily 666 3 1
lily@LLY:~/test/ipc$ ./ipc_msg.py 1 2 r
Recv Success.(3 bytes):
abc
lily@LLY:~/test/ipc$ ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
0x00000001 65536 lily 666 0 0
lily@LLY:~/test/ipc$ ./ipc_msg.py 1 c
lily@LLY:~/test/ipc$ ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
lily@LLY:~/test/ipc$
怎么样?和之前的C语言版本一模一样吧?