[心得]利用python併發提速上線測試效率

背景

在我們的工作中,分佈式的生產環境要求我們提高測試效率。原先的上線job串行執行,嚴重製約了我們的上線效率。

我們從兩個層面來解決問題:jenkins job層面,設置裏面勾選Execute concurrent builds if necessary來實現多job並行。腳本層面,引入python併發來解決腳本內串行的問題。

取捨

關於多線程還是多進程的取捨。
如果是IO密集型,線程和進程都可以,相對而言,線程稍複雜。
如果是cpu密集型,那麼多進程更合理。

線程

線程模型如下:
做一個線程池,總數爲cpu數加1,每一個子類無限循環。

# coding=utf-8
from Queue import Queue
from threading import Thread
from single import *


class ProcessWorker(Thread):
    def __init__(self, queue):
        Thread.__init__(self)
        self.queue = queue

    def run(self):
        while True:
            # Get the work from the queue
            num = self.queue.get()
            processNum(num)
            self.queue.task_done()


def main():
    ts = time()
    nums = getNums(4)
    # Create a queue to communicate with the worker threads
    queue = Queue()
    # Create 4 worker threads
    for x in range(4):
        worker = ProcessWorker(queue)
        # Setting daemon to True will let the main thread exit even though the workers are blocking
        worker.daemon = True
        worker.start()
    # Put the tasks into the queue
    for num in nums:
        queue.put(num)
    # Causes the main thread to wait for the queue to finish processing all the tasks
    queue.join()
    print("cost time is: {:.2f}s".format(time() - ts))


if __name__ == "__main__":
    main()

進程

每當線程中的一個準備工作時,進程可以不斷轉換線程。使用Python或其他有GIL的解釋型語言中的線程模塊實際上會降低性能。如果你的代碼執行的是CPU密集型的任務,例如解壓gzip文件,使用線程模塊將會導致執行時間變長。對於CPU密集型任務和真正的並行執行,我們可以使用多進程(multiprocessing)模塊。
官方的Python實現——CPython——帶有GIL.

爲了使用多進程,我們得建立一個多進程池。通過它提供的map方法,我們把URL列表傳給池。

# coding=utf-8
from functools import partial
from multiprocessing.pool import Pool
from single import *
from time import time


def main():
    ts = time()
    nums = getNums(4)
    p = Pool(4)
    p.map(processNum, nums)
    print("cost time is: {:.2f}s".format(time() - ts))


if __name__ == "__main__":
    main()

關於併發和並行的理解

併發是指,程序在運行的過程中存在多於一個的執行上下文。這些執行上下文一般對應着不同的調用棧。

在單處理器上,併發程序雖然有多個上下文運行環境,但某一個時刻只有一個任務在運行。

但在多處理器上,因爲有了多個執行單元,就可以同時有數個任務在跑。

這種物理上同一時刻有多個任務同時運行的方式就是並行。

和併發相比,並行更加強調多個任務同時在運行。

而且並行還有一個層次問題,比如是指令間的並行還是任務間的並行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章