web端自動化——python多線程


Python通過兩個標准庫thread和threading提供對線程的支持。thread提供了低級別的、原始的線程以及一個簡單的鎖。threading基於Java的線程模型設計。

鎖(Lock)條件變量(Condition)在Java中是對象的基本行為(每一個對象都自帶了鎖和條件變量),而在 Python中則是獨立的對象。

注意:我們應該避免使用thread模塊,原因是thread模塊不支持守護線程。當主線程退出時,所有的子線程不管它們是否還在工作,都會被強行退出。

threading模塊支持守護線程。

 

1、進程與線程的區別:

 

2、multiprocessing多進程模塊

多進程multiprocessing模塊的使用與多線程threading模塊的用法類似。multiprocessing提供了本地和遠程的並發性,有效地通過全局解釋鎖(Global InterceptorLock,GIL)來使用進程(而不是線程)。由於GIL的存在,在CPU密集型的程序當中,使用多線程並不能有效地利用多核CPU的優勢,因為一個解釋器在同一時刻只會有一個線程在執行。所以,multiprocessing模塊可以充分利用硬件的多處理器來進行工作。它支持UNlX和Windows系統上的運行。

3、threading 多線程模塊

threading模塊支持守護線程。

 

4、Pipe和Queue

multiprocessing提供threading包中沒有的IPC(進程間通信),效率上更高。應優先考慮Pipe和Queue,避免使用Lock/Event/Semaphore/Condition等同步方式(因為它們根據的不是用戶進程的資源)。

multiprocessing包中有Pipe類和Queue類來分別支持這兩種IPC機制。Pipe和Queue 可以用來傳送常見的對象。

①    Pip可以是單向化(half-duplex),也可以是雙向(duplex)。我們通過multiprocessing.Pipe (duplex=False)創建單向管道(默認為雙向)。一個進程從pipe—端輸入對象,然后被pipe 另一端的進程接收。單向管道只允許管道一端的進程輸入,而雙向管道則允許從兩端輸入。

Pipe.py

import multiprocessing

def proc1(pipe):

    pipe.send('hello')

    print('proc1 rec:', pipe.recv())

def proc2(pipe):

    print('proc2 rec:', pipe.recv())

    pipe.send('hello, too')

if __name__ == "__main__":

    multiprocessing.freeze_support()

    pipe = multiprocessing.Pipe()

    p1 = multiprocessing.Process(target=proc1,args=(pipe[0],))

    p2 = multiprocessing.Process(target=proc2,args=(pipe[1],))

    p1.start()

    p2.start()

    p1.join()

    p2.join()

這里的pipe是雙向的。pipe對象建立的時候,返回一個含有兩個元素的表,每個元素 代表pipe的一端(Connection對象)。我們對pipe的某一端調用send()方法來傳送對象,在另一端使用recv()來接收。

②     Queue類與Pipe相類似,都是先進先出結構。但Queue類允許多個進程放入,多個進程從隊列取出對象。Queue類使用Queue (maxsize)創建,maxsize表示隊列中可以存放對象的最大數量。

queue.py

import multiprocessing

import os, time

def inputQ(queue):

    #getpid是獲得當前進程的進程號。系統每開辟一個新進程就會為他分配一個進程號。

    info = str(os.getpid()) + '(put):'+str(time.time())

    #put方法用以插入數據到隊列中

    queue.put(info)

def outputQ(queue, lock):

    #get方法可以從隊列讀取並且刪除一個元素

    info = queue.get()

    lock.acquire()

    print((str(os.getpid()) + '(get):'+info))

    lock.release()

if __name__=='__main__':

    record1 =[]

    record2 =[]

    lock = multiprocessing.Lock()#加鎖,為防止散亂的打印

    queue = multiprocessing.Queue(3)

    for i in range(10):

        process = multiprocessing.Process(target=inputQ,args=(queue,))

        process.start()

        record1.append(process)

    for i in range(10):

        process = multiprocessing.Process(target=outputQ,args=(queue,lock))

        process.start()

        record2.append(process)

    for p in record1:

        p.join()

    for p in record2:

        p.join()

    queue.close() #沒有更多的對象進來,關閉queue

 

5、多線程分布式執行測試用例

Selenium Grid只是提供多系統、多瀏覽器的執行環境,Selenium Grid本身並不提供並行的執行測試用例,這個我們在前面己經反復強調。下面就通過演示使用多線程技術結合Selenium Grid實現分布式並行地執行測試用例。

啟動 Selenium Server

在本機打開兩個命令提示符窗口。

本機啟動一個主hub和一個node節點(端口號別分為4444和5555),本機IP地址為: 172.16.101.239。

>java -jar selenium-server-standalone-2.47.0.jar -role hub

>java -jar selenium-server-standalone-2.47.0.jar -role node -port 5555

啟動一個遠程的node(設罝端口號為6666),IP地址假設為:172.16.101.238。

>java -jar selenium-server-standalone-2.47.jar -role node -port 6666 -hub http://172.16.101.239:4444/grid/register

運行測試腳本。

grid_thread.py

from threading import Thread

from selenium import webdriver

from time import sleep,ctime

#測試用例

def test_baidu(host,browser):

    print('start:%s' %ctime())

    print(host, browser)

    dc = {'browserName':browser}

    driver = webdriver.Remote(conunand_executor=host,

                              desired_capabilities=dc)

    driver.get('http://www.baidu.com')

    driver.find_element_by_id("kw").send_keys(browser)

    driver.find_element_by_id("su").click()

    sleep(2)

    driver.quit()

if __name__ =='__main__':   

#啟動參數(指定運行主機與瀏覽器)

    lists = {'http://127.0.0.1:4444/wd/hub': 'chrome',

             'http://127.0.0.1:5555/wd/hub': 'internet explorer',

             'http://172.16.101.238:6666/wd/hub':'firefox', # 遠程節點

             }

    threads =[]

    files = range(len(lists))

    #創建線程

    for host, browser in lists.items():

            t = Thread(target=test_baidu, args=(host, browser))

            threads.append(t)

    #啟動線程

    for i in files:

        threads[i].start()

    for i in files:

        threads [i].join()

    print('end:%s' %ctime())

 

 6、多線程執行測試用例

from threading import Thread
from selenium import webdriver
from time import ctime,sleep
#測試用例
def test_baidu(browser,search):
print('start:%s' %ctime())
print('browser:%s ,' %browser)
if browser == "chrome":
driver = webdriver.Chrome()
elif browser == "ff":
driver = webdriver.Firefox()
else:
print('browser參數有誤,只能為ff、chrome')
driver.get('http://www.baidu.com')
driver.find_element_by_id("kw").send_keys(search)
driver.find_element_by_id('su').click()
sleep(2)
driver.quit()
if __name__ == "__main__":
#啟動參數(指瀏覽器與百度搜索內容)
lists ={'chrome':'threading', 'ff':'python'}
threads =[]
files = range(len(lists))
#創建線程
for browser, search in lists.items():
t = Thread(target=test_baidu,args=(browser,search))
threads.append(t)
#啟動線程
for t in files:
threads[t].start()
for t in files:
threads[t].join()
print('end:%s' %ctime())


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM