# 0x03 共享变量

## 共享变量

多进程中的每个进程与多线程中不同, 是不会共享变量的, 所使用的变量每个进程都会独自拷贝一份, 如果使用共享变量, 直接使用Python中的对象是不可行的:

```python
import os
from multiprocessing import Process

vip_list = []

def testFunc(cc):
    vip_list.append(cc)
    print('process id:', os.getpid())

if __name__ == '__main__':
    threads = []

    for ll in range(10):
        t = Process(target=testFunc, args=(ll,))
        t.daemon = True
        threads.append(t)

    for i in range(len(threads)):
        threads[i].start()

    for j in range(len(threads)):
        threads[j].join()

    print("------------------------")
    print('process id:', os.getpid())
    print(vip_list)
```

输出的结果为:

```
python aa.py
process id: 632
process id: 635
process id: 637
process id: 633
process id: 636
process id: 634
process id: 639
process id: 638
process id: 641
process id: 640
------------------------
process id: 619
[]
```

可以看到, 我们想让所有的进程把结果都存入到`vip_list`中, 但是每个进程都不会把结果存进去, 仍然是一个空列表. 这是因为`vip_list`列表不是一个共享变量, 不能被子进程使用.

可以使用`multiprocessing`包自带的共享变量类来实现. 其中的**Value**, **Array**以及**Manager**类都可以作为共享变量, 被多个进程共享使用.

* **Value**: 共享数值
* **Array**共享列表

```python
from multiprocessing import Process, Value, Array

def f(n, a):
    n.value = 3.1415927
    for i in range(len(a)):
        a[i] = -a[i]

if __name__ == '__main__':
    num = Value('d', 0.0)
    arr = Array('i', range(10))

    p = Process(target=f, args=(num, arr))
    p.start()
    p.join()

    print num.value
    print arr[:]
```

结果为:

```
3.1415927
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
```

* **Manager**: 支持多种形式, `list`, `dict`等Python对象以及`Value`, `Array`和`Queue`, `Event`, `Lock`等并行同步工具. 只需要调用`Manager`对象对应的属性.

  \`\`\`python import os from multiprocessing import Process, Manager, Lock

  lock = Lock() manager = Manager() sum = manager.Value('tmp', 0)

def testFunc(cc, lock): with lock: sum.value += cc

if **name** == '**main**': threads = \[]

```
  for ll in range(100):
      t = Process(target=testFunc, args=(1, lock))
      t.daemon = True
      threads.append(t)

  for i in range(len(threads)):
      threads[i].start()

  for j in range(len(threads)):
      threads[j].join()

  print("------------------------")
  print('process id:', os.getpid())
  print(sum.value)
```

\`\`\`

## 参考资料

[浅谈 python multiprocessing（多进程）下如何共享变量](https://my.oschina.net/leejun2005/blog/203148)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://kerasnoone.gitbook.io/garnet/gong-cheng-zhan/python/bing-fa/duo-jin-cheng/0x03-gong-xiang-bian-liang.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
