python socket

草稿,未完待續:

json.dumps  序列化(將數據變成字符串格式)python

head_json.encode('utf-8')  將字符串編譯成bytes格式。json

 

 struct提供用format specifier方式對數據進行打包和解包(將數字轉成固定長度的bytes格式)多線程

 

 

套接字只能發送bytes格式的數據併發

只有字符能編碼成bytes格式,數字等其它類型的數據不能編碼成bytes格式。app

 

進程、線程

Socket實現併發

 

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密集型任務有優點,對計算密集型任務沒有優點。

建立線程1

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)

建立線程2

建立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

退出主線程

死鎖:

兩把鎖互相等待對方釋放,

相關文章
相關標籤/搜索