上一篇文章: Python进程专题5:进程间通讯
下一篇文章: Python进程专题7:托管对象
咱们如今知道,进程之间彼此是孤立的,惟一通讯的方式是队列或管道,但要让这两种方式完成进程间通讯,底层离不开共享内容,这就是今天的主角:共享内存。
v=Value(typecode,arg1,...,argN,lock): typecode:要么是包含array模块使用的相同类型代码(如'i'、'd'等)的字符串,要么是来自ctypes模块的类型对象 (例如:ctypes.c_int,ctypes.c_double等)。 arg1,...,argN:传递给构造函数的参数。 lock:只能使用关键字传入的参数,默认为True:将建立一个新锁来保护对值的访问。若是传入一个现有锁,该锁将用于进行同步。 访问底层的值:v.value
r=RawValue(typecode,arg1,...,argN):同Value对象,惟一区别是不存在lock
a=Array(typecode,initializer,lock):在共享内存中建立ctypes数组。 initializer:要么是设置数组初始大小的整数,要么是项序列,其值和大小用于初始化数组。 能够使用标准的Python索引、切片、迭代操做访问它,其中每项操做均→锁进程同步, 对于字节字符串,a还具备a.value属性,能够把整个数组当作一个字符串进行访问。
r=RawArray(typcode,initlizer):同Array,单不存在锁。当所编写的程序必须一次性操做大量的数组项时, 若是同时使用这种数据类型和用于同步的单独大的锁,性能将极大提高。
原语 | 描述 |
---|---|
Lock | 互斥锁 |
RLock | 可重入的互斥锁(同一个进程能够多吃得到它,同时不会形成阻塞) |
Semaphore | 信号量 |
BoundedSemaphore | 有边界的信号量 |
Event | 事件 |
Condition | 条件变量 |
代码:segmentfault
#使用共享数组代替管道,将一个由浮点数组成的Python列表发送给另一个进程 import multiprocessing class FloatChannel(object): def __init__(self,maxsize): #在共享内存中建立一个试数组 self.buffer=multiprocessing.RawArray('d',maxsize) #在共享内存中建立ctypes对象 self.buffer_len=multiprocessing.Value('i') #定义一个信号量1表明:empty self.empty=multiprocessing.Semaphore(1) #定义一个信号量0表明:full self.full=multiprocessing.Semaphore(0) def send(self,values): #只在缓存为null时继续 #acquire()会阻塞线程,直到release被调用 self.empty.acquire() nitems=len(values) print("保存内容的长度",nitems) #设置缓冲区大小 self.buffer_len.value=nitems #将值复制到缓冲区中 self.buffer[:nitems]=values print(self.buffer[:nitems]) #发信号通知缓冲区已满 self.full.release() def recv(self): #只在缓冲区已满时继续 self.full.acquire() #复制值 values=self.buffer[:self.buffer_len.value] #发送信号,通知缓冲区为空 self.empty.release() return values #性能测试,接受多条消息 def consume_test(count,ch): #for i in range(count): values=ch.recv() print("接收到的值:",values) #性能测试,发送多条消息 def produce_test(count,values,ch): #for i in range(count): print("发送:",values) ch.send(values) if __name__=="__main__": ch=FloatChannel(10000) p=multiprocessing.Process(target=consume_test,args=(1000,ch)) p.start() values=[float(x) for x in range(10)] produce_test(10,values,ch) print("done") p.join()
结果:数组
发送: [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0] 保存内容的长度 10 [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0] done 接收到的值: [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]