在代码优化的过程中,碰到了这样一个问题:一个进程中我定义了几个全局变量,然后我又Process了几个子进程,子进程中是否可以各自对全局变量进行修改?最后全局变量会取哪个值呢?

经过一番尝试以后得到结果:

  子进程继承父进程的全局变量,而且是以复制的形式完成,所以子进程修改后的全局变量只对自己和自己的子进程有影响。

  父子进程不共享这些全局变量,也就是说:父进程中对全局变量的修改不影响子进程中的全局变量,同理,子进程也不影响父进程的。

为了实现父子进程的通信,在网上经过了一番翻找以后,找到了 Value和Array 方法

  Value函数返回一个shared memory包装类,其中包含一个ctypes对象

    一般 整数用 i, 字符用 c,浮点数用 d 就可以了

  Array函数返回一个shared memory包装类,其中包含一个数组,字符串需要用 Array 来传递

  • @args shared memory 中包含的值
  • @lock 默认值是True:创建一个新的lock来控制对value的访问。该参数也可以是 multiprocessing.Lock 或 multiprocessing.RLock 对像,用来控制对value的访问

================================================================================================================================  

案例一:

def worker(num, mystr, arr):
num.value *= 2
mystr.value = "ok"
for i in range(len(arr)):
arr[i] = arr[i] * (-1) + 1.5 def dump_vars(num, mystr, arr):
print 'num: ', num.value
print 'str: ', mystr[:]
print 'arr: ', arr[:] if __name__=='__main__':
num = Value('i', 5)
mystr = Array('c', 'just for test')
arr = Array('d', [1.0, 1.5, -2.0])
dir(str)
print 'init value'
dump_vars(num, mystr, arr) ps = [Process(target=worker, args=(num, mystr, arr)) for x in range(3)]
for p in ps:
p.start()
for p in ps:
p.join() print
print 'after all workers finished'
dump_vars(num, mystr, arr)
#结果:
init value
num: 5
str: just for test
arr: [1.0, 1.5, -2.0] after all workers finished
num: 40
str: ok

多次测试我发现,在共享字符串的时候,在主进程中的初始化决定了这个字符串的长度,
创建后字符串的长度固定不变,相当于把这个字符串所在的地址复制给一个指针,并且在字符串的首地址记录了自身的长度,
在以后读取这个值的时候就会去读取那一段固定长度的内容,而不管现在的新内容长度是多少,举个例子:
比如我们在主进程初始化一段字符串 "abcde",一旦初始化,长度就固定了,现在长度是5,然后我们在其他进程赋值,我们尝试赋值为
"abcdefg",此时执行会报错,因为长度超标了,我们在赋值为
"yes",最后输出结果为
"yes&efg"(此处的&是代表一个不可显示的字符,不同的环境下显示不同,有可能显示空格,有可能显示null)。也就是说长短都不行,必须和初始化字符串等长。
于是得出这样一个结论,如果你要共享一个字符串,那么在子进程中赋值时必须赋值长度相当的字符串。建议在子进程中可以先检查字符串长度,然后在根据需要拼接指定长度的字符串

案例二:

from multiprocessing import Process, Value, Array

def f(n, a):
n.value = n.value + 1
for i in range(len(a)):
a[i] = a[i] * 10 if __name__ == '__main__':
num = Value('i', 1)
arr = Array('i', range(10)) p = Process(target=f, args=(num, arr))
p.start()
p.join() print(num.value)
print(arr[:]) p2 = Process(target=f, args=(num, arr))
p2.start()
p2.join() print(num.value)
print(arr[:]) # the output is :
#
# [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
#
# [0, 100, 200, 300, 400, 500, 600, 700, 800, 900]

python - 多进程 Value、Array应用记录的更多相关文章

  1. Python多进程使用

    [Python之旅]第六篇(六):Python多进程使用   香飘叶子 2016-05-10 10:57:50 浏览190 评论0 python 多进程 多进程通信 摘要:   关于进程与线程的对比, ...

  2. python多进程断点续传分片下载器

    python多进程断点续传分片下载器 标签:python 下载器 多进程 因为爬虫要用到下载器,但是直接用urllib下载很慢,所以找了很久终于找到一个让我欣喜的下载器.他能够断点续传分片下载,极大提 ...

  3. python 多进程开发与多线程开发

    转自: http://tchuairen.blog.51cto.com/3848118/1720965 博文作者参考的博文:  博文1  博文2 我们先来了解什么是进程? 程序并不能单独运行,只有将程 ...

  4. Python多进程池 multiprocessing Pool

    1. 背景 由于需要写python程序, 定时.大量发送htttp请求,并对结果进行处理. 参考其他代码有进程池,记录一下. 2. 多进程 vs 多线程 c++程序中,单个模块通常是单进程,会启动几十 ...

  5. 【转】【Python】Python多进程与多线程

    1.1 multiprocessing multiprocessing是多进程模块,多进程提供了任务并发性,能充分利用多核处理器.避免了GIL(全局解释锁)对资源的影响. 有以下常用类: 类 描述 P ...

  6. Python多进程库multiprocessing创建进程以及进程池Pool类的使用

    问题起因最近要将一个文本分割成好几个topic,每个topic设计一个regressor,各regressor是相互独立的,最后汇总所有topic的regressor得到总得预测结果.没错!类似bag ...

  7. python课程第二周重点记录

    python课程第二周重点记录 1.元组的元素不可被修改,元组的元素的元素可以被修改(字典在元组中,字典的值可以被修改) 2.个人感觉方便做加密解密 3.一些方法的使用 sb = "name ...

  8. Python多进程编程

    转自:Python多进程编程 阅读目录 1. Process 2. Lock 3. Semaphore 4. Event 5. Queue 6. Pipe 7. Pool 序. multiproces ...

  9. Python多进程(1)——subprocess与Popen()

    Python多进程方面涉及的模块主要包括: subprocess:可以在当前程序中执行其他程序或命令: mmap:提供一种基于内存的进程间通信机制: multiprocessing:提供支持多处理器技 ...

  10. Python多进程multiprocessing使用示例

    mutilprocess简介 像线程一样管理进程,这个是mutilprocess的核心,他与threading很是相像,对多核CPU的利用率会比threading好的多. import multipr ...

随机推荐

  1. inetd - 因特网“超级服务”

    总览 inetd - [ -d ] [ -q 队列长度 ] [ 配置文件名 ] 描述 inetd通常在系统启动时由/etc/rc.local引导.inetd会监听指定internet端口是否有连接要求 ...

  2. [工具] BurpSuite--Intruder功能

    BurpSuite--Intruder功能 0x00 配置说明 intruder是进行爆破的,基本流程是标注请求的爆破参数,然后配置字段,选择爆破方式进行爆破,下面来记录下工具的使用 选中intrud ...

  3. Java并发编程实战 第13章 显式锁

    接口Lock的实现类: ReentrantLock, ReentrantReadWriteLock.ReadLock, ReentrantReadWriteLock.WriteLock Reentra ...

  4. Java基本的程序结构设计 基本类型的输入输出

    读取输入: java.util.Scanner 一个可以使用正则表达式来分析基本类型和字符串的简单文本扫描器. 了解: Scanner 使用分隔符模式将其输入分解为标记,默认情况下该分隔符模式与空白匹 ...

  5. asp.net mvc + vue.js + axios.js

    1.新建一个 MVC 应用程序 2.右键解决方案 添加VUE 3.搜索vue 1.安装axios.js ,用于数据请求,get , post axios

  6. cursor-spacing 软键盘和input的距离

    指定光标与键盘的距离,单位 px .取 input 距离底部的距离和 cursor-spacing 指定的距离的最小值作为光标与键盘的距离. 例: 软键盘和input的距离300px

  7. 【NOIP2016提高A组模拟9.15】Map

    题目 分析 发现,当原图是一棵树的时候,那么新建一条边后,就会变成环套树, 而环内的所有点对都是安全点对,如果环中有k个点,答案就是\(k(k-1)\) 联想到,当把原图做一遍tarjan缩点,每个环 ...

  8. spark的accumulator值保存在哪里?

    答案:保存在driver端.因此需要对收集的信息的规模要加以控制,不宜过大.避免 driver端的outofmemory问题!!!

  9. 计时器 GC垃圾回收 demo

    计时器: public void start() { //定义计时器 Timer timer=new Timer(); //定义运行间隔(数字越小,速度越快) int interval=30; //创 ...

  10. ETL工具之kittle使用案例整理

    主花了一下午时间,收集全网,学习了下kittle,觉得该大v写的不错,特意整理给大家!学会这几个案例kittle基本就没问题了. 1.kettle案例一抽取gz格式文本内容保存到mongodb  ht ...