python 多進程

 衆所周知,python本身是單線程的,python中的線程處理是由python解釋器分配時間片的;但在python 3.0中吸收了開源模塊,開始支持系統原生的進程處理——multiprocessing.

注意:這個模塊的某些函數需要操作系統的支持,例如,multiprocessing.synchronize模塊在某些平臺上引入時會激發一個ImportError

1)Process
  要創建一個Process是很簡單的。
  1. from multiprocessing import Process
  2. def f(name):
  3.     print('hello', name)
  4. if __name__ == '__main__':
  5.      p = Process(target=f, args=('bob',))
  6.      p.start()
  7.      p.join()
  要獲得一個Process的進程ID也是很簡單的。
  1. from multiprocessing import Process
  2. import os
  3. def info(title):
  4.     print title
  5.     print 'module name:', __name__
  6.     print 'parent process:', os.getppid()#這個測試不通過,3.0不支持
  7.     print 'process id:', os.getpid()
  8. def f(name):
  9.     info('function f')
  10.     print 'hello', name
  11. if __name__ == '__main__':
  12.     info('main line')
  13.     p = Process(target=f, args=('bob',))
  14.     p.start()
  15.     p.join()
  創建進程:multiprocessing.Process([group[, target[, name[, args[, kargs]]]]])
  參數:
  group:    None,它的存在僅僅是爲了與threading.Thread兼容
  target:   一般是函數
  name:     進程名
  args:     函數的參數
  kargs:    keywords參數

  函數:
  run()                  默認的run()函數調用target的函數,你也可以在子類中覆蓋該函數
  start()                啓動該進程
  join([timeout])        父進程被停止,直到子進程被執行完畢。
                         當timeout爲None時沒有超時,否則有超時。
                         進程可以被join很多次,但不能join自己
  is_alive()             
  terminate()            結束進程。
                         在Unix上使用的是SIGTERM
                         在Windows平臺上使用TerminateProcess

  屬性:
  name                   進程名
  daemon                 守護進程
  pid                    進程ID
  exitcode               如果進程還沒有結束,該值爲None
  authkey                    
            
2)Queue
  Queue類似於queue.Queue,一般用來進程間交互信息
  例子:
  1. from multiprocessing import Process, Queue
  2. def f(q):
  3.     q.put([42None'hello'])
  4.  if __name__ == '__main__':
  5.      q = Queue()
  6.      p = Process(target=f, args=(q,))
  7.      p.start()
  8.      print(q.get())    # prints "[42, None, 'hello']"
  9.      p.join()
  注意:Queue是進程和線程安全的。
  Queue實現了queue.Queue的大部分方法,但task_done()和join()沒有實現。    
  創建Queue:multiprocessing.Queue([maxsize])
  函數:
  qsize()                             返回Queue的大小
  empty()                             返回一個boolean值表示Queue是否爲空
  full()                              返回一個boolean值表示Queue是否滿
  put(item[, block[, timeout]])       
  put_nowait(item)
  get([block[, timeout]])
  get_nowait()
  get_no_wait()

  close()                             表示該Queue不在加入新的元素
  join_thread()                       
  cancel_join_thread()

3)JoinableQueue
  創建:multiprocessing.JoinableQueue([maxsize])
  task_done()
  join()

4)Pipe
  1. from multiprocessing import Process, Pipe
  2. def f(conn):
  3.     conn.send([42None'hello'])
  4.     conn.close()
  5. if __name__ == '__main__':
  6.     parent_conn, child_conn = Pipe()
  7.     p = Process(target=f, args=(child_conn,))
  8.     p.start()
  9.     print(parent_conn.recv())   # prints "[42, None, 'hello']"
  10.     p.join()
  multiprocessing.Pipe([duplex])      返回一個Connection對象

5)異步化synchronization

  1. from multiprocessing import Process, Lock
  2. def f(l, i):
  3.     l.acquire()
  4.     print('hello world', i)
  5.     l.release()
  6. if __name__ == '__main__':
  7.     lock = Lock()
  8.     for num in range(10):
  9.         Process(target=f, args=(lock, num)).start()
6)Shared Memory
  1. from multiprocessing import Process, Value, Array
  2. def f(n, a):
  3.     n.value = 3.1415927
  4.     for i in range(len(a)):
  5.         a[i] = -a[i]
  6. if __name__ == '__main__':
  7.     num = Value('d'0.0)
  8.     arr = Array('i', range(10))
  9.     p = Process(target=f, args=(num, arr))
  10.     p.start()
  11.     p.join()
  12.     print(num.value)
  13.     print(arr[:])
1>Value
2>Array

7)Manager
  1. from multiprocessing import Process, Manager
  2. def f(d, l):
  3.     d[1] = '1'
  4.     d['2'] = 2
  5.     d[0.25] = None
  6.     l.reverse()
  7. if __name__ == '__main__':
  8.     manager = Manager()
  9.     d = manager.dict()
  10.     l = manager.list(range(10))
  11.     p = Process(target=f, args=(d, l))
  12.     p.start()
  13.     p.join()
  14.     print(d)
  15.     print(l)

8)Pool
  1. from multiprocessing import Pool
  2. def f(x):
  3.     return x*x
  4. if __name__ == '__main__':
  5.     pool = Pool(processes=4)              # start 4 worker processes
  6.     result = pool.apply_async(f, [10])     # evaluate "f(10)" asynchronously
  7.     print result.get(timeout=1)           # prints "100" unless your computer is *very* slow
  8.     print pool.map(f, range(10))          # prints "[0, 1, 4,..., 81]"
multiprocessing.Pool([processes[, initializer[, initargs]]])

函數:
  apply(func[, args[, kwds]])
  apply_async(func[, args[, kwds[, callback]]])
  map(func,iterable[, chunksize])
  map_async(func,iterable[, chunksize[, callback]])
  imap(func, iterable[, chunksize])
  imap_unordered(func, iterable[, chunksize])
  close()
  terminate()
  join()

  1. from multiprocessing import Pool
  2. def f(x):
  3.     return x*x
  4. if __name__ == '__main__':
  5.     pool = Pool(processes=4)              # start 4 worker processes
  6.     result = pool.apply_async(f, (10,))   # evaluate "f(10)" asynchronously
  7.     print(result.get(timeout=1))          # prints "100" unless your computer is *very* slow
  8.     print(pool.map(f, range(10)))         # prints "[0, 1, 4,..., 81]"
  9.     it = pool.imap(f, range(10))
  10.     print(next(it))                       # prints "0"
  11.     print(next(it))                       # prints "1"
  12.     print(it.next(timeout=1))             # prints "4" unless your computer is *very* slow
  13.     import time
  14.     result = pool.apply_async(time.sleep, (10,))
  15.     print(result.get(timeout=1))          # raises TimeoutError
    

9)雜項
multiprocessing.active_children()          返回所有活動子進程的列表
multiprocessing.cpu_count()                返回CPU數目
multiprocessing.current_process()          返回當前進程對應的Process對象
multiprocessing.freeze_support()
multiprocessing.set_executable()

10)Connection對象
send(obj)
recv()
fileno()
close()
poll([timeout])
send_bytes(buffer[, offset[, size]])
recv_bytes([maxlength])
recv_bytes_info(buffer[, offset])  
  1. >>> from multiprocessing import Pipe
  2. >>> a, b = Pipe()
  3. >>> a.send([1'hello'None])
  4. >>> b.recv()
  5. [1'hello'None]
  6. >>> b.send_bytes('thank you')
  7. >>> a.recv_bytes()
  8. 'thank you'
  9. >>> import array
  10. >>> arr1 = array.array('i', range(5))
  11. >>> arr2 = array.array('i', [0] * 10)
  12. >>> a.send_bytes(arr1)
  13. >>> count = b.recv_bytes_into(arr2)
  14. >>> assert count == len(arr1) * arr1.itemsize
  15. >>> arr2
  16. array('i', [0123400000])
發佈了130 篇原創文章 · 獲贊 4 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章