多線程的使用

来源:http://www.cnblogs.com/Chenjiabing/archive/2017/09/03/7471485.html
-Advertisement-
Play Games

多線程 前言 我看了不止一個人說多線程是雞肋,但是就依照我個人覺得多線程在一些小型的爬蟲中還是可以顯著的提高速度的,相比多進程來說應該還是挺簡單的 使用多線程 繼承threading.Thread 繼承threading.Thread模塊是一個很好的一個選擇,就像java中也是可以繼承類和實現介面一 ...


多線程

前言

我看了不止一個人說多線程是雞肋,但是就依照我個人覺得多線程在一些小型的爬蟲中還是可以顯著的提高速度的,相比多進程來說應該還是挺簡單的

使用多線程

繼承threading.Thread

繼承threading.Thread模塊是一個很好的一個選擇,就像java中也是可以繼承類和實現介面一樣,這都是很好的選擇,下麵我們來看看具體如何使用

class Mythread(threading.Thread):
    def __init__(self,threadID,name,counter):
        threading.Thread.__init__(self)    #首先需要先保留原來threading.Thread中的初始化函數
        self.threadID=threadID      #重命名線程的ID
        self.name=name              #線程的名字
        self.counter=counter        #線程的數量

    def run(self):
        lock.acquire()      #獲取線程鎖Lock
        for i in range(10):
            print "線程"+self.name+"開始運行"
        lock.release()      #釋放線程鎖Lock
if __name__ == '__main__':
    lock=threading.Lock()     
    t1=Mythread(0,"thread-1",3)
    t2=Mythread(1,"thread-2",3)

    t1.start()
    t2.start()

    threads=[]
    threads.append(t1)
    threads.append(t2)
    for t in threads:
        t.join()                #阻塞主線程,直至線程運行完畢才運行main線程的語句
    print "線程運行結束"

需要註意的是,這種繼承的方式有一個缺點,這個和java中繼承來實現多線程是一樣的,就是一個對象只能是對應一個線程,並不能一個對象被多個線程共用,下麵我們將會介紹另外的一種方式

直接調用threading.Thread

上面我們說過繼承的方式,但是我個人覺得對於一些比較小的爬蟲還是有些繁瑣的,因為總是需要重寫run方法,現在我們來看看如何簡化實現多線程

"""
這是一個簡單的例子,其實也不是一個好的例子,但是為了演示方便就選用了,可以看出這裡是直接調用
了func函數,然後變成多個線程同時並行,其中target是要調用的方法(沒有括弧),args是方法調用需要傳入的參數
其實這個還是和上面的繼承比較相似的
"""
def func(name,age):
    for i in range(10):
        print name+"的年齡為:"+str(age)       
t=threading.Thread(target=func,args=["陳加兵",22])
t.start()

Thread對象的相關方法

  • start() 啟動線程
  • join([timeout]) 設置阻塞線程,timeout是可選的參數,表示阻塞的時間,如果沒有就是當此線程運行結束才開始運行下一個線程
  • run() 線程活動的方法
  • getName() 獲取線程名稱
  • setName() 設置線程的名稱
  • isAlive() 判斷線程是否還活著
  • isDaemon() 判斷是否是守護線程
  • setDaemon() 設置為守護線程,守護線程就是當主線程運行完後,這個線程也會隨著主線程的結束而結束

共用隊列

從源代碼可以看出隊列是實現了鎖原語的,因此可以使用隊列實現線程的同步,這裡的主要原理就不細說了,簡單的說就是get和put等方法都實現了鎖原語,就是當一個操作正在執行的時候其他的操作會阻塞等待

下麵我自己寫了一個使用兩個線程實現同時入隊和出隊的程式

import random
import time
from Queue import Queue
class myThread(threading.Thread):
    def __init__(self,threadID,name,counter,q,flag):
        """
        threadID是線程的ID
        name是線程的名稱
        q是先進先出隊列
        flag是用來調用get和put的標誌
        """
        threading.Thread.__init__(self)
        self.name=name
        self.threadID=threadID
        self.counter=counter
        self.q=q
        self.flag=flag   
        
    def run(self):
        """
        當flag為1時就調用put方法,否則調用get
        """
        if self.flag==1:
            self.put()
        else:
            self.get()
            

    def put(self):
        while True:
            self.q.put(random.randint(0,10))
    
    def get(self):
        while True:
            if not self.q.empty():
                print self.q.get()
            
        
            

            
if __name__=="__main__":

    threadLock=threading.Lock()
    q=Queue()
    
    t1=myThread(1,"Thread-1",1,q,1)
    t2=myThread(2,"Thread-2",2,q,2)
    
    threads=[]
    
    threads.append(t1)
    threads.append(t2)
    
    t1.start()
    t2.start()
     
    

Queue相關的一些方法

  1. Queue.qsize() 返回隊列的大小
  2. Queue.empty() 如果隊列為空,返回True,反之False
  3. Queue.full() 如果隊列滿了,返回True,反之False
  4. Queue.full 與 maxsize 大小對應
  5. Queue.get([block[, timeout]])獲取隊列,timeout等待時間
  6. Queue.get_nowait() 相當Queue.get(False)
  7. Queue.put(item) 寫入隊列,timeout等待時間
  8. Queue.put_nowait(item) 相當Queue.put(item, False)
  9. Queue.task_done() 在完成一項工作之後, Queue.task_done()函數向任務已經完成的隊列發送一個信號
  10. Queue.join() 實際上意味著等到隊列為空,再執行別的操作

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、WCF技術我該如何學習? 阿笨的回答是:作為初學者的我們,那麼請跟著阿笨一起玩WCF吧,阿笨將帶領大家如何以正確的姿勢去掌握WCF技術。由於WCF技術知識點太多了,就純基礎概念性知識都可以單獨出一本書來講解,本次分享課程《C#面向服務編程技術WCF從入門到實戰演練》開課之前,阿笨還是希望從沒瞭解 ...
  • 開篇先來說一下我和來畫的故事,以及寫這篇文章的初衷。 今年年初時,我還在北京,在 Face++,做著人臉識別技術的 Windows 和 Android 端,做著人工智慧終將實現世間所有美好的夢。這時的我已經離開 UWP,甚至 C# 很久了,寫著 C++ 和 Java,當時真的沒想過會再次回到 UWP ...
  • 自己畫一個轉圈圈的控制項 ...
  • 首先說一下foreach有的也叫增強for迴圈,foreach其實是for迴圈的一個特殊簡化版。 再說一下foreach的書寫格式: for(元素類型 元素名稱 : 遍曆數組(集合)(或者能進行迭代的)){ 語句 } foreach雖然是for迴圈的簡化版本,但是並不是說foreach就比for更好 ...
  • 特別聲明本隨筆copy於egon(林海峰)。 一 IO模型介紹 為了更好地瞭解IO模型,我們需要事先回顧下:同步、非同步、阻塞、非阻塞 同步(synchronous) IO和非同步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分別是什麼,到底有 ...
  • 建立資料庫訪問類的封裝 <?php class DBDA { public $host = "localhost"; //伺服器地址 public $uid = "root"; //資料庫的用戶名 public $pwd = ""; //資料庫的密碼 public $dbname = "";//數據 ...
  • Spring與SpringMVC整合! 問:實際上SpringMVC就運行在Spring環境之下,還有必要整合麽?SpringMVC和Spring都有IOC容器,是不是都需要保留呢? 答案是:通常情況下,類似於數據源,事務,整合其他框架都是放在spring的配置文件中(而不是放在SpringMVC的 ...
  • 冒泡排序是一種非常常見的排序演算法。如同水中的一排泡泡,先冒出最大的一個泡泡。再冒出剩餘泡泡中的最大泡泡,依次類推,它的排序規則如下: 1. 從第一個元素開始,比較相鄰的兩個元素,如果後面的小於前面的,交換兩個的位置,一直比較到最後一個 2. 迴圈1中的操作,但已經確定的最大的元素不再參與比較 3. ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...