01-多線程技術(shù)
# -*- coding: utf-8 -*-
# @Author: KingJX
# @Date : 2018/8/8
-
python內(nèi)置的threading模塊,可以支持多線程
所有的進(jìn)程默認(rèn)都有一個(gè)線程(一般叫這個(gè)線程為主線程), 其他進(jìn)程叫做子線程
如果想要在線程中添加其他進(jìn)程,就創(chuàng)建線程對象
import threading
import time
def download(file):
print('開始下載', file)
time.sleep(5)
print(file, '下載結(jié)束')
if __name__ == '__main__':
# 1.創(chuàng)建線程對象
"""
target: 需要在子線程中執(zhí)行的函數(shù)
args: 調(diào)用函數(shù)的實(shí)參列表
返回值是一個(gè)線程對象
"""
thread1 = threading.Thread(target=download, args=['愛情公寓'])
# 2.在子線程中執(zhí)行任務(wù)
thread1.start()
thread2 = threading.Thread(target=download, args=['狄仁杰'])
thread2.start()
# download('愛情公寓')
# download('狄仁杰')
print('======')
輸出結(jié)果:
開始下載 愛情公寓
開始下載 狄仁杰
======
狄仁杰 愛情公寓 下載結(jié)束
下載結(jié)束
02-多線程技術(shù)2
-
方式2: 寫一個(gè)自己的線程類
- 寫一個(gè)類繼承Thread類
- 重寫run方法,在里面來規(guī)定需要在子線程中執(zhí)行的任務(wù)
- 實(shí)現(xiàn)在子線程中執(zhí)行的任務(wù)對應(yīng)的功能,如果需要參數(shù),通過類的對象屬性來傳值
from threading import Thread
import requests
import re
# 下載數(shù)據(jù)
class DownloadThread(Thread):
"""下載類"""
def __init__(self, file_path):
super().__init__()
self.file_path = file_path
def run(self):
"""run方法"""
"""
寫在這個(gè)方法中的內(nèi)容就是在子線程中執(zhí)行的內(nèi)容
這個(gè)方法不要直接調(diào)用
"""
print('開始下載')
response = requests.request('GET', self.file_path)
data = response.content
suffix = re.search(r'\.\w+$', self.file_path).group()
with open('./git'+suffix, 'wb') as f:
f.write(data)
print('下載完成')
if __name__ == '__main__':
d1 = DownloadThread('http://yuting.local/shareX/Git.exe')
# 通過start間接調(diào)用run方法,run方法中的任務(wù)在子線程中執(zhí)行
# d1.start()
d2 = DownloadThread('http://www.sheng-han.com/images/webwxgetmsgimg.jpg')
d2.start()
03-多線程的應(yīng)用_1
import socket
from threading import Thread
class ConversationThread(Thread):
"""在子線程中處理不同的客戶端會話"""
"""
python中可以在函數(shù)參數(shù)的后面加一個(gè)':'來對參數(shù)的類型,進(jìn)行說明
"""
def __init__(self, conversation:socket.socket, address):
super().__init__()
self.conversation = conversation
self.address = address
def run(self):
while True:
self.conversation.send('hello'.encode())
print(self.address, self.conversation.recv(1024).decode(encoding='utf-8'))
if __name__ == '__main__':
server = socket.socket()
server.bind(('10.7.181.59', 8080))
server.listen(512)
while True:
conversation, address = server.accept()
t = ConversationThread(conversation, address)
t.start()
03-多線程的應(yīng)用_1
import socket
if __name__ == '__main__':
client = socket.socket()
client.connect(('10.7.181.117', 8080))
while True:
daat1 = client.recv(1024)
print(daat1.decode(encoding='utf-8'))
message = input('>>>')
client.send(message.encode())
05-join函數(shù)
from threading import Thread, currentThread
import time
from random import randint
class DownLoad(Thread):
def __init__(self, file):
# 這兒父類的init方法必須調(diào)用,否則當(dāng)前這個(gè)類創(chuàng)建的對象沒有新的線程
super().__init__()
self.file = file
def run(self):
print('開始下載:%s' % self.file)
time.sleep(randint(5, 10))
print('%s下載結(jié)束' % self.file)
if __name__ == '__main__':
# time.time(): 獲取當(dāng)前時(shí)間 - 時(shí)間戳
start_time = time.time()
t1 = DownLoad('最強(qiáng)Z.mp4')
t1.start()
t2 = DownLoad('黃金城.mp4')
t2.start()
# 獲取當(dāng)前線程
"""
主線程: MainThread
子線程: Thread-數(shù)字(數(shù)字從1開始)
"""
print(currentThread())
# 如果一個(gè)操作想要在另外一個(gè)子線程中的任務(wù)執(zhí)行完成后再1執(zhí)行,就在當(dāng)前任務(wù)前用子線程對象調(diào)用join()方法
# 所以join會阻塞線程,阻塞到對應(yīng)的子線程中的任務(wù)執(zhí)行完為止
t1.join()
t2.join()
end_time = time.time()
print('總共消耗時(shí)間:%.2f' % (end_time - start_time))