1. 程式人生 > >python多線程和多進程(一)

python多線程和多進程(一)

5.0 16px time img 繼承 total 線程鎖 nco 第一次

一、多線程

  1. Python的標準庫提供了兩個模塊:_threadthreading_thread是低級模塊,threading是高級模塊,對_thread進行了封裝。絕大多數情況下,只需要使用threading這個模塊。
    import threading
    from time import ctime,sleep
    def func1(func): print u" 我是函數%s.此刻打印時間: %s" %(func,ctime()) sleep(5) print u%s再次打印時間%s % (func,ctime())
    def func2(func):
    print u"我是函數 %s此刻打印時間: %s" %(func,ctime()) sleep(5) print u%s再次打印時間%s%(func,ctime())
    threads
    = [] t1 = threading.Thread(target=func1,args=(func1,)) #創建線程,args傳參必須以元組方式傳入 threads.append(t1) t2 = threading.Thread(target=func2,args=(func2,))#創建線程,args傳參必須以元組方式傳入
    threads.append(t2)
    if __name__
    == __main__:
    for t in threads:
    # t.setDaemon(True) #設置守護線程(主線程退出,子線程也會退出,不會掛起占用資源)
    t.start() #啟動線程
    print u腳本結束時間%s%ctime()

    運行結果:(註意setDaemon())

    我是函數func1.此刻打印時間: Fri Sep 07 15:43:15 2018
    我是函數 func2此刻打印時間: Fri Sep 07 15:43:15 2018
    腳本結束時間Fri Sep 07 15:43:15 2018  #(三個都是同一時間打印)

    func1再次打印時間Fri Sep 07 15:43:20 2018 func2再次打印時間Fri Sep 07 15:43:20 2018 #(兩個都為等待5秒後同事打印)

    說明;func1,func2都是同時一時間執行任務了,但是為什麽腳本結束時間先打印了,原因是主線程被分成兩個子線程同時運行,但是子線程有等待5秒但主線程沒有等待就直接執行了打印了;

  2. 我們稍作改進:
    import threading
    from time import ctime,sleep
    def func1(func):
        print u" 我是函數%s.此刻打印時間: %s" %(func,ctime())
        sleep(5)
        print u%s再次打印時間%s % (func,ctime())
    def func2(func):
    
        print u"我是函數 %s此刻打印時間: %s" %(func,ctime())
        sleep(5)
        print u%s再次打印時間%s%(func,ctime())
    threads = []
    t1 = threading.Thread(target=func1,args=(func1,))
    threads.append(t1)
    t2 = threading.Thread(target=func2,args=(func2,))
    threads.append(t2)
    
    if __name__ == __main__:
        for t in threads:
            # t.setDaemon(True) #設置守護線程(主線程退出,子線程也會退出,不會掛起占用資源)
            t.start()
        for t in threads:
    t.join() # 等待線程執行結束
    print u腳本結束時間%s%ctime()
    我是函數func1.此刻打印時間: Fri Sep 07 16:09:29 2018
    我是函數 func2此刻打印時間: Fri Sep 07 16:09:29 2018
    func1再次打印時間Fri Sep 07 16:09:34 2018
    func2再次打印時間Fri Sep 07 16:09:34 2018
    腳本結束時間Fri Sep 07 16:09:34 2018
    

      主線程執行到技術分享圖片,然後等待子線程;

  3. 上個第一次使用線程寫東西的項目吧,去年剛開始寫爬蟲因為數量多所以網上到處找資料,東拼西湊總算給我搞出來了 技術分享圖片
    #encoding:utf-8
    import requests
    import threading
    from lxml import etree
    import codecs,csv
    
    
    def return_link():
        Link = []
        for  i in range(2000):
            url="http://www.xzgsj.gov.cn/baweb/show/shiju/gg.jsp?fenceid=95000000&total=45192&queryType=6&pagenum="+str(i)+"&action=gg.jsp?ssid=ZxSlh1DBkGGpV2hnWMSt5PG7f8FPjTbvH78vJ1nFcwYyMhWzGBzy!1470507879!1500631589968&findWenhao=&findName="
            Link.append(url)
        return  Link
    
    
    def get_href():
        while True:
            lock.acquire()
            if len(Link) == 0:
                lock.release()
                break
            else:
                url = Link.pop(0)
                lock.release()
                r = requests.get(url, headers=headers).content
                print url
                pages = etree.HTML(r.decode(utf-8))
                a = pages.xpath(u"//table[@width=‘700‘]/tr[position()>1]/td/a/@onclick")
                for i in a:
                    a = i.replace(javaScript:window.open(\‘, ‘‘).replace(\‘,\‘a\‘,\‘width=550 height=350\‘), ‘‘)
                    url = http://www.xzgsj.gov.cn/baweb/show/shiju/ + a
                    with codecs.open(url.csv,ab) as f:
                        w = csv.writer(f)
                        w.writerow([url])
    
    if __name__ == __main__:
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"
        }
        lock = threading.Lock()#線程鎖
        Link = return_link()
        tasks = []  # 任務列表
        for x in range(5):
            t = threading.Thread(target=get_href)  # 準備線程函數及參數
            t.setDaemon(True)  # 設置守護線程(主線程退出,子線程也會退出,不會掛起占用資源)
            tasks.append(t)
        for t in tasks:
            t.start()  # 啟動多線程(任務列表有多少個值,就會啟動多少個線程)
        for t in tasks:
            t.join()  # 等待線程執行結束
    View Code
  4. 使用Threading模塊創建線程,直接從threading.Thread繼承,然後重寫__init__方法和run方法:(和第一個例子一樣只是基於類的使用)
    import threading
    from time import ctime,sleep
    
    class myThread(threading.Thread):  # 繼承父類threading.Thread
        def __init__(self, threadID, name, counter):
            threading.Thread.__init__(self)
            self.threadID = threadID
            self.name = name
            self.counter = counter
        def run(self):  # 把要執行的代碼寫到run函數裏面 線程在創建後會直接運行run函數
            print "Starting " + self.name,u時間{}.format(ctime())
            sleep(5)
            print "Exiting " + self.name,u時間{}.format(ctime())
    
    # 創建新線程
    thread1 = myThread(1, "Thread-1", 1)
    thread2 = myThread(2, "Thread-2", 2)
    
    # 開啟線程
    tasks = []
    tasks.append(thread1)
    tasks.append(thread2)
    if __name__ == __main__:
        for t in tasks:
            # t.setDaemon(True) #設置守護線程(主線程退出,子線程也會退出,不會掛起占用資源)
            t.start()
        for t in tasks:
            t.join()  # 等待線程執行結束
        print u腳本結束時間%s%ctime()
    結果:
    Starting Thread-1 時間Fri Sep 07 17:13:53 2018
    Starting Thread-2 時間Fri Sep 07 17:13:53 2018
    Exiting Thread-1 時間Fri Sep 07 17:13:58 2018
    Exiting Thread-2 時間Fri Sep 07 17:13:58 2018
    腳本結束時間Fri Sep 07 17:13:58 201

  5. 第一篇over,以後想到再加吧

python多線程和多進程(一)