一、進(jìn)程
1、什么是進(jìn)程
在系統(tǒng)中正在運(yùn)行的一個(gè)應(yīng)用程序
特點(diǎn):每個(gè)進(jìn)程之間是獨(dú)立的回季,每個(gè)進(jìn)程運(yùn)行在其專用且受保護(hù)的內(nèi)存空間內(nèi)
2、線程
- 什么是線程
- 1個(gè)進(jìn)程想要執(zhí)行任務(wù)正林,必須得有線程(至少有一個(gè))
- 進(jìn)程的所有任務(wù)都在線程中執(zhí)行
-
特點(diǎn):
串行:如果想要在1個(gè)進(jìn)程中執(zhí)行多個(gè)任務(wù)泡一,那么每個(gè)任務(wù)只能按順序逐個(gè)執(zhí)行(同一時(shí)間1個(gè)線程只能執(zhí)行1個(gè)任務(wù))
3、多線程
a. 什么是多線程
- 1個(gè)進(jìn)程中可以開啟多條線程觅廓,每條線程可以并行(同時(shí))(執(zhí)行不同的任務(wù))
- 多線程可以提高程序的執(zhí)行效率
b. 多線程的原理
- 注意:同一時(shí)間鼻忠,CPU只能處理一條線程,只有1條線程在工作(執(zhí)行)
- 多線程并發(fā)(同時(shí))執(zhí)行杈绸,其實(shí)CPU快速地在多線程之間進(jìn)行調(diào)度(切換)
- 劣勢:線程很多時(shí)會(huì)大量消耗CPU資源
每條線程被調(diào)度執(zhí)行的頻次會(huì)降低(線程執(zhí)行效率降低)
二帖蔓、多線程程序
- 每個(gè)程序在運(yùn)行的時(shí)候(進(jìn)程)系統(tǒng)都會(huì)為這個(gè)進(jìn)程創(chuàng)建一個(gè)線程矮瘟,這個(gè)程序叫主線程,程序員自己創(chuàng)建的線程叫子線程
- 多個(gè)任務(wù)在一個(gè)線程中是按順序一個(gè)一個(gè)執(zhí)行的(線程串行)
- 多線程的任務(wù)同時(shí)執(zhí)行
import datetime
import time
from random import randint
def download(file):
print(file, threading.current_thread()) # 獲取當(dāng)前線程
print(datetime.datetime.now(), '開始下載:%s' % file)
# sleep(時(shí)間):會(huì)阻塞當(dāng)前線程指定的時(shí)間(單位:秒)
time.sleep(randint(5, 10))
print(datetime.datetime.now(), '下載 %s 結(jié)束' % file)
# python中怎么創(chuàng)建線程
# 通過threading標(biāo)準(zhǔn)庫來支持多線程
import threading
if __name__ == '__main__':
print(threading.current_thread())
# 創(chuàng)建一個(gè)線程對象
# 方法1:
# threading.Thread(target=, args=)
# target:需要傳一個(gè)需要在子線程中執(zhí)行的函數(shù)(類型是function的變量)
# args: 在子線程中調(diào)用target對應(yīng)的函數(shù)時(shí)塑娇,該傳什么參數(shù)芥永,以元祖的形式傳入
# t1 = threading.Thread(target=download, args=('我不好',))
# t2 = threading.Thread(target=download, args=('你好不',))
# 讓子線程執(zhí)行任務(wù)
# t1.start()
# t2.start()
from threading import Thread, current_thread
from datetime import datetime
# a. 寫一個(gè)類繼承Thread類
class DownloadThread(Thread):
"""這是一個(gè)下載線程類"""
# 如果需要給run方法中傳數(shù)據(jù),通過當(dāng)前類的屬性來傳
def __init__(self, file):
super().__init__()
self.file = file
def run(self):
print(current_thread())
print(datetime.now(), '開始下載:%s' % self.file)
# b. 重寫當(dāng)前類的run方法,run方法的任務(wù)就是在子線程需要執(zhí)行的任務(wù)
# c. 創(chuàng)建當(dāng)前類的對象怠噪,就是線程對象泛范,然后還是調(diào)用start執(zhí)行線程中任務(wù)
t1 = DownloadThread('aaaa')
# 注意:如果需要將run方法中的內(nèi)容在子線程執(zhí)行,就必須通過start方法間接調(diào)用run方法,
# 如果直接調(diào)用run方法荣刑,run方法里面的內(nèi)容只會(huì)在主線程里執(zhí)行,不會(huì)再子線程執(zhí)行
t1.start()
import socket
from threading import Thread, current_thread
class ConversationThread(Thread):
def __init__(self, conversation:socket.socket, addr):
super().__init__()
self.conversation = conversation
self.addr = addr
def run(self):
# 保持通話
while True:
message = self.conversation.recv(1024).decode('utf-8')
print(self.addr[0], ':', message)
# 發(fā)送消息
self.conversation.send('hello'.encode('utf-8'))
def create_server():
# 創(chuàng)建服務(wù)
sever = socket.socket()
# 綁定ip和端口
sever.bind(('10.7.156.141', 8080))
# 監(jiān)聽端口
sever.listen(100)
print('開始監(jiān)聽')
while True:
# 創(chuàng)建回話
print('等待連接......')
conversation, addr = sever.accept()
print(conversation)
print(addr)
# 創(chuàng)建處理這個(gè)請求的子線程對象
t1 = ConversationThread(conversation, addr)
t1.start()
# 此時(shí)進(jìn)程結(jié)束的條件是所有子線程全部結(jié)束或崩潰
if __name__ == '__main__':
create_server()