json.dumps 序列化(將數據變成字符串格式)python
head_json.encode('utf-8') 將字符串編譯成bytes格式。json
struct提供用format specifier方式對數據進行打包和解包(將數字轉成固定長度的bytes格式)多線程
套接字只能發送bytes格式的數據併發
只有字符能編碼成bytes格式,數字等其它類型的數據不能編碼成bytes格式。app
Self.Request就是conn;異步
import socketserver
#Ftpserver(conn, client_addr, obj)
class FTPserver(socketserver.BaseRequestHandler): #通信 #必須建立一個類,必須繼承這個方法(固定死的)
def handle(self): #必須建立handle這個函數(固定死的)
print('=-=====>',self.request)
print(self.request)
while True:
data=self.request.recv(1024)
print(data)
self.request.send(data.upper())
if __name__ == '__main__':
obj=socketserver.ThreadingTCPServer(('127.0.0.1',8080),FTPserver) #建立線程,一個線程就是一個服務員,多線程就是多個服務員。
print(obj.server_address)
print(obj.RequestHandlerClass)
print(obj.socket)
obj.serve_forever() #連接循環socket
實現多線程函數
開啓一個子線程:使用threading模塊ui
並行:多進程同時運行,不須要切換編碼
併發:多進程之間切換運行,切換調節:
#子線程繼承父線程的setDaemon的狀態,主(注意不是父)線程默認爲false;true爲守護線程,false爲非守護線程。主線程執行結束會強行關閉守護線程,須要等待非守護線程執行完才結束。
#IO操做不佔用CPU,而且遇到IO操做直接執行其餘線程。GIL鎖規定單一進程只能實現併發,不能實現並行。結合以上兩個緣由得出結論:多線程對IO密集型任務有優點,對計算密集型任務沒有優點。
import threading
import time
def foo(n):
time.sleep(n)
print("foo....%s" % n)
print(threading.activeCount()) #總共有多少個線程
def bar(n):
time.sleep(n)
print("bar......%s" % n)
s=time.time()
t1=threading.Thread(target=foo,args=(2,)) #建立線程對象,args=(線程數,)
#t1.setDaemon(True) #設置爲守護線程
t1.start() #開啓線程
t2=threading.Thread(target=bar,args=(5,))
#t2.setDaemon(True)
t2.start()
t1.join() # 阻塞主線程
t2.join()
print("++++++",threading.activeCount())
print("ending!")
print("cost time:",time.time()-s)
# foo(4)
# bar(5)
建立10個線程
進程:由程序、數據集、進程控制塊三部分組成。
線程是最小的執行單元。
進程是最小的資源管理單元,進程是在一個數據集上正在運行的程序。管理着數據集和線程。
進程和線程的關係:
(1) 一個線程只能屬於一個進程,一個進程至少有一個或多個線程。
(2) 資源分配給進程,同一進程的全部線程共享該進程的全部資源。
(3) 操做系統把CPU分給線程,即真正在CPU上運行的是線程。
進程和線程切換的原則:
一、時間片(很是短的時間)
二、遇到IO操做(sleep,input,accept)[不佔用CPU]就切換。
三、優先級切換,優先切換到優先級高的。
建立子線程:
對象名=Threading.Thread(target=函數,args=(線程數,)
對象名.start() #開啓子線程。
join函數:子線程調用不結束,下面的代碼不執行
守護進程:守護線程和主線程共進退,等待非守護線程執行完退出
子線程繼承父線程是不是守護線程的特徵。也就是說若是父線程是守護線程,那麼子線程也是守護線程。。。
多線程比較適合IO密集型,若是用於計算密集型反而會下降效率。
同步:進程在執行某個請求時,一直等待返回數據以後才執行下面的代碼。
異步:異步雙方不須要共同的時鐘,不阻塞當前線程,容許後續操做。(全程無阻塞)
總結了一句話不知道對不對:IO密集型任務就是異步。
Python中函數,類和模塊有本身的名稱空間。
多線程處理相同數據源的數據時,若是有IO會出現阻塞和切換,從而致使計算結果不許確。
保證共享數據操做的完整性。每一個對象都對應一個"互斥鎖" ,保證只能有一個線程訪問該對象。
互斥鎖只加處處理數據的代碼上。
互斥鎖的建立:
import threading
R=threading.Lock()
R.acquire() ''' 對公共數據的操做 ''' R.release() |
import threading
import time
def sub():
global num # 掌握爲何加global num
lock.acquire() #獲取鎖
temp=num
time.sleep(0.1 )
num=temp-1
lock.release() #釋放鎖
time.sleep(2)
num=100
l=[]
lock=threading.Lock() #建立互斥鎖對象
for i in range(100):
t=threading.Thread(target=sub,args=())
t.start()
l.append(t)
for t in l:
t.join()
print(num)
互斥鎖的講解:
多線程的優點在於能夠同時運行多個任務(至少感受起來是這樣)。可是當線程須要共享數據時,可能存在數據不一樣步的問題。
考慮這樣一種狀況:一個列表裏全部元素都是0,線程"set"從後向前把全部元素改爲1,而線程"print"負責從前日後讀取列表並打印。
那麼,可能線程"set"開始改的時候,線程"print"便來打印列表了,輸出就成了一半0一半1,這就是數據的不一樣步。爲了不這種狀況,引入了鎖的概念。
鎖有兩種狀態——鎖定和未鎖定。每當一個線程好比"set"要訪問共享數據時,必須先得到鎖定;若是已經有別的線程好比"print"得到鎖定了,那麼就讓線程"set"暫停,也就是同步阻塞;等到線程"print"訪問完畢,釋放鎖之後,再讓線程"set"繼續。
通過這樣的處理,打印列表時要麼所有輸出0,要麼所有輸出1,不會再出現一半0一半1的尷尬場面。
實例:
#!/usr/bin/python3
import threading
import time
class myThread (threading.Thread):
def __init__(self, threadID, name, counter):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
def run(self):
print ("開啓線程: " + self.name)
# 獲取鎖,用於線程同步
threadLock.acquire()
print_time(self.name, self.counter, 3)
# 釋放鎖,開啓下一個線程
threadLock.release()
def print_time(threadName, delay, counter):
while counter:
time.sleep(delay)
print ("%s: %s" % (threadName, time.ctime(time.time())))
counter -= 1
threadLock = threading.Lock()
threads = []
# 建立新線程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)
# 開啓新線程
thread1.start()
thread2.start()
# 添加線程到線程列表
threads.append(thread1)
threads.append(thread2)
# 等待全部線程完成
for t in threads:
t.join()
print ("退出主線程")
執行以上程序,輸出結果爲:
開啓線程: Thread-1
開啓線程: Thread-2
Thread-1: Wed Apr 6 11:52:57 2016
Thread-1: Wed Apr 6 11:52:58 2016
Thread-1: Wed Apr 6 11:52:59 2016
Thread-2: Wed Apr 6 11:53:01 2016
Thread-2: Wed Apr 6 11:53:03 2016
Thread-2: Wed Apr 6 11:53:05 2016
退出主線程
兩把鎖互相等待對方釋放,