多线程和多进程最大的不同在于,多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响,而多线程中,所有变量都由所有线程共享,所以,任何一个变量都可以被任何一个线程修改,因此,线程之间共享数据最大的危险在于多个线程同时改一个变量,把内容给改乱了。

不同进程之间内存是不共享的,要实现两个进程间的数据交换,可以用以下方法:

queues

使用方法和threading里面的queue差不多

from multiprocessing import Process,Queue

def f(q):
q.put([2,None,'hello']) if __name__ =='__main__':
q = Queue()
p = Process(target=f,args=(q,))
p.start()
print(q.get())
p.join()

运行结果

[2, None, 'hello']

多进程中,对于一个变量,每个进程都是复制了一份,所以每个进程之间修改数据互不影响。 Queue()方法相当于第三方,把进程A的数据序列化后传给进程B 反序列化得到数据。并不是一个共享的变量。而是实现了数据的传递。

Pipes 管道

类似于socket 一端发送,一端接收,实现通信。

from multiprocessing import Process,Pipe

def f(conn):
conn.send([5,'hello'])
conn.close() if __name__ =='__main__':
parent_conn,child_conn = Pipe()
p = Process(target=f,args=(child_conn,))
p.start()
print(parent_conn.recv())
p.join()

运行结果

[5, 'hello']

发送方和接收方的关系,也和socket类似,发送方发送几次,接收方就要接收几次。接收方如果接收的次数多于发送方,那么接收方就会卡住,直到发送方在发送一次。

相互通信

def f(conn):
conn.send([5,'hello']) #发送数据
print(conn.recv()) #接收数据
conn.close() if __name__ =='__main__':
parent_conn,child_conn = Pipe()
p = Process(target=f,args=(child_conn,))
p.start()
print(parent_conn.recv()) #接收数据
parent_conn.send("hehe你好") #发送数据
p.join()

Managers

由manager()返回的manager对象控制一个包含Python对象的服务器进程,并允许其他进程使用代理来操作它们。

由manager()返回的管理器将支持类型列表、命令、名称空间、锁、RLock、信号量、BoundedSemaphore、Condition、Event、Barrier、Queue、Value和Array。

from multiprocessing import Process, Manager

def f(d, l):
d[1] = '1'
d['2'] = 2
d[0.25] = None
l.append(1)
print(l) if __name__ == '__main__':
with Manager() as manager:
d = manager.dict() #生成一个字典,可以在多个进程中传递和共享。 l = manager.list(range(5)) #生成一个列表,在多个进程中传递和共享。
p_list = [] #存放进程对象
for i in range(10):
p = Process(target=f, args=(d, l))
p.start()
p_list.append(p)
for res in p_list:
res.join() #等待进程结束 print(d)
print(l)

运行结果

[0, 1, 2, 3, 4, 1]
[0, 1, 2, 3, 4, 1, 1]
[0, 1, 2, 3, 4, 1, 1, 1]
[0, 1, 2, 3, 4, 1, 1, 1, 1]
[0, 1, 2, 3, 4, 1, 1, 1, 1, 1]
[0, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1]
[0, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1]
[0, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1]
[0, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[0, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
{0.25: None, 1: '1', '2': 2}
[0, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

以上实现了进程之间的数据共享,不是数据传递,而是真正的共享。并且可以同时修改。

Manager()内部有加锁机制,不允许两个进程同时修改一份数据,因为进程的数据是独立的。

最新文章

  1. 放弃安卓原生TimePicker,选择wheelView打造更漂亮的时间get,以及动态拉伸输入框布局,这些,这里都有!
  2. 使用Axis2编写webservice客户端,服务端
  3. bat 结束进程
  4. 修改Tomcat服务器的默认端口号
  5. PostgreSQL trigger (function) examples
  6. 【转载】COM 连接点
  7. iOS线程
  8. 《view programming guide for iOS 》之可以使用动画效果的属性
  9. HeadFirst jsp 02 (体系结构)
  10. 统计学习导论:基于R应用——第四章习题
  11. 【转】 Linux中的工作队列
  12. OC 冒泡排序 -- 核心代码
  13. C#中KeyDown和KeyPress区别
  14. 图片切割工具---产生多个div切割图片 采用for和一的二维阵列设置背景位置
  15. C++中#和##的特殊使用
  16. java中的注解总结
  17. IO 调优
  18. SQL性能优化应该考虑哪些?
  19. mac subLime3 JSON 格式化插件安装
  20. [Canvas]Bombman v1.00

热门文章

  1. Q767 重构字符串
  2. Linux云服务器下Tomcat部署
  3. 仔细说明CLOSE_WAIT状态的原因
  4. Java_break与continue区别
  5. Oracle PL/SQL编程之函数
  6. Netbeans8的中文乱码
  7. train,dev,test数据集作用
  8. Mac新手问题
  9. 手动修改user-agent
  10. 获取单个checkbox选中项