python學習筆記——線程threading (一)

1 線程threading

1.1 基本概述

也被稱爲輕量級的進程。html

線程是計算機多任務編程的一種方式,能夠使用計算機的多核資源。python

線程死應用程序中工做的最小單元編程

1.2 線程特色

(1)進程的建立開銷較大,線程建立開銷較小安全

(2)一個進程中能夠包含多個線程多線程

(3)線程依附於進程的存在,多個線程共享進程的資源併發

(4)每一個線程也擁有本身獨特的特徵,好比ID、指令集app

注意:ide

(1)進程有獨立的空間,數據安全性較高函數

(2)線程使用進程的資源,即通常使用全局變量的方式進行線程間通訊,因此須要較複雜的同步互斥ui

(3)多個不相關的線程功能最好不要湊到一塊兒造成線程

1.3 線程與進程

(1)進程是線程的容器,一個程序的執行實例就是一個進程,線程是進程的實際運做單位。

(2)進程是系統進行資源分配調度的基本單元,是操做系統結構的基礎;線程是操做系統可以運算調度的最小單位。

(3)進程之間是相互隔離的,即一個進程既沒法訪問其餘進程的內容,也沒法操做其餘進程,而操做系統會跟蹤全部正在運行的進程,給每一個進程一小段運行時間,而後切換到其餘進程。

(4)python的線程沒有優先級,沒有線程組的概念,也不能被銷燬、中止、掛起,天然也沒有恢復、中斷。 

 

2 線程模塊

Thread module emulating a subset of Java's threading model

2.1 線程模塊之類

Thread,Event, Lock, Rlock, Condition, [Bounded]Semaphore, Timer, local。

2.2 線程模塊之方法屬性

方法:

threading.current_thread():返回當前的線程變量。 

threading.active_count():

threading.stack_size()

threading.enumerate():返回一個包含正在運行的線程的list。正在運行指線程啓動後、結束前,不包括啓動前和終止後的線程。

threading.setprofile(func)

threading.Lock()

threading.Rlock()

屬性:

t = threading.Thread(target=function),t爲線程實例

t.name:線程的名稱

t.getName:得到線程名字

t.is_alive:獲取線程的狀態

2.3 線程模塊之常量

threading.TIMEOUT_MAX 設置threading全局超時時間。

3 Thread類

3.1 Thread類

class Thread(builtins.object)的Methods defined here:

Thread(self, group=None, target=None, name=None, args=(), kwargs=None, *, daemon=None)

group:線程組,目前沒有實現,爲了未來實現ThreadGroup類的擴展而設置的。

target:要執行的方法,run()方法調用的對象

name:線程名,在默認狀況下,命名爲Thread-N(N爲最小的十進制數字)

args:元組參數

kwargs:字典參數

3.2 Thread類的實例方法:

start():啓動線程

join(self, timeout=None):等待線程結束,阻塞線程直到調用此方法的線程終止或到達指定的的timeout

is_alive():返回線程是否在運行,運行返回True;

isAlive:等價於is_alive()

getName():獲取線程名字

setName():設置線程名字,在threading.Thread()的幫助文檔中沒有該方法,其餘資料上有。

 

is/setDaemon(bool): 獲取/設置是後臺線程(默認前臺線程(False))。(在start以前設置)

  若是是後臺線程,主線程執行過程當中,後臺線程也在進行,主線程執行完畢後,後臺線程不論成功與否,主線程和後臺線程均中止
       若是是前臺線程,主線程執行過程當中,前臺線程也在進行,主線程執行完畢後,等待前臺線程也執行完成後,程序中止

3.3 線程的建立方法

線程的建立方法有兩種

一種是利用threading.Thread()直接建立線程

import threading import time def music(sec): print('播放音樂') time.sleep(sec) t = threading.Thread(name='createthread',target=music,args=(2,)) t.start() print("結束!")

運行

播放音樂 結束!

 

另外是利用 threading.Thread() 類的繼承、並重寫 run() 來建立線程

import threading import time class MyThread(threading.Thread): def __init__(self,arg): # 注意:必定要顯式的調用父類的初始化函數。
        super(MyThread, self).__init__() self.arg=arg # 定義每一個線程要運行的函數
    def run(self): time.sleep(1) print('the arg is:%s\r' % self.arg) for i in range(3): t =MyThread(i) t.start() print('main thread end!')

運行

main thread end! the arg is:0 the arg is:1 the arg is:2

3.4 線程傳參

事實上:線程傳參與函數傳參沒有明顯區別,本質上就是函數傳參 

import threading def add(x, y): print('{} + {} = {}'.format(x, y, x + y, threading.current_thread())) # 建立線程對象
thread1 = threading.Thread(target=add, name='add', args=(4, 5)) thread2 = threading.Thread(target=add, name='add', args=(4,), kwargs={'y': 5}) thread3 = threading.Thread(target=add, name='add', kwargs={'x': 4, 'y': 5}) # 啓動線程
thread1.start() thread2.start() thread3.start()

運行

4 + 5 = 9
4 + 5 = 9
4 + 5 = 9

關於format函數參看 python的format函數python中強大的format函數

3.5 線程中的變量

import threading import time a = 10

def music(sec): print('播放音樂') print(a) time.sleep(sec) print(a) t = threading.Thread(name='mythread',target=music,args=(2,)) t.start() print("------------main--------------") time.sleep(2) a = 100

運行

# 第一次運行
播放音樂 10
------------main--------------
100
# 第二次運行 播放音樂 10 ------------main-------------- 10

說明:

(1)同一個程序,運行後的結果不相同,由於在一樣sleep(2)後,全局變量從新綁定了100,而進程最後打印出變量a,若變量a先綁定100,則會打印出100,若先打印則爲10

(2)將args=(2,)變爲args=(3,),則會穩定打印出100

(3)將全局變量的前的sleep(2)變爲sleep(3),則結果穩定打印出10

 

示例2

import threading import time a = 10

def music1(sec): a = 1000
    print('m11',a) time.sleep(sec) print('m12',a) def music2(sec): print('m21',a) time.sleep(sec) print('m22',a) t1 = threading.Thread(name='mythread1',target=music1,args=(2,)) t2 = threading.Thread(name='mythread2',target=music2,args=(3,)) t1.start() t2.start() print("------------main--------------") # time.sleep(2)
a = 100

運行

m11 1000
------------main-------------- m21 10 m12 1000 m22 100

3.6 線程中的屬性方法

import threading import time def music(sec): print('播放音樂') time.sleep(sec) t = threading.Thread(name='mythread',target=music,args=(2,)) t.start() print('name:',t.name)#線程名稱
t.setName("yourthread")#設置線程的名稱

print('name:',t.name)#線程名稱
print('getName:',t.getName())# 得到線程名稱
print('is_alive:',t.is_alive()) #獲取線程狀態
 t.join()#阻塞等待進程退出
print("------------main--------------")

運行

播放音樂 name: mythread name: yourthread getName: yourthread is_alive: True ------------main--------------

3.7 在本地計算機上能夠建立線程的最大數量

# 查看能夠建立多少線程 # 能夠用top查看CPU運行狀況
import threading import time a = 0 def music(sec): global a a += 1 time.sleep(sec) print(a) # 阻塞建立的線程退出
    while True: pass thread_list = [] while True: t = threading.Thread(target=music,args=(2,)) t.start() #啓動線程
 thread_list.append(t) for i in thread_list: i.join()#阻塞等待線程退出

數據顯示,能夠建立2961個線程,同時在新的終端上top查看CPU運行達到100%

 

相關參考:

python 併發和線程

python--threading多線程總結

python併發編程之多線程

相關文章
相關標籤/搜索