[TOC=1,5]
>[success] # 線程和進程
~~~
1.線程是操作系統能夠進行運算調度的最小單位。
2.他被包含在進程之中,是進程中的實際運作單位。一條線程指的是進程中的一個單一順序的控制流,一個進程中可以并發多個線程,每個線程并行執行不同的任務。
3.進程:要以一個整體的形式暴露給操作系統管理,里面包含對各種資源的調用,堆存的管理,網絡接口調用等,對資源管理的集合就可以成為進程
4.線程:是操作系統最小的調度單位,是一串指令的集合
5.進程 要操作cpu,必須要創建一個線程~
大白話解釋:
1.電腦有固定的內存,我們可以吧應用程序理解成進程,當我們打開各種各樣的應用程序的時候,我們的內存就會越來越小,這是因為進程調度內存空間,
2.不同進程占用不同的空間相互不進行干涉,可以理解成qq程序崩潰不會影響到word程序,線程在進程中,線程會跟cup進行聯系調度,
3.如果qq進程中 一個線程崩潰,會導qq進程的崩潰~簡單理解進程就是劃分程序要用的內存,里面包含著一些線程,進程會跟cup進行運算的調度
~~~
>[success] # 簡單的使用線程
>[danger] ##### 簡單使用線程
* 不使用線程
~~~
1.當第一個countdown(10) 執行完后執行countdown(5),是一個串行效果
~~~
~~~
import time
def countdown(n):
while n > 0:
print('T-minus', n)
n -= 1
time.sleep(1)
countdown(10)
countdown(5)
打印結果:
T-minus 5
T-minus 4
T-minus 3
T-minus 2
T-minus 1
T-minus 2
T-minus 1
~~~
* 使用線程
~~~
1.使用線程中有兩個參數,Thread(target=, args= ),target是目標函數,args是目標函數參數,但是是元組形式
2.start 調用線程
3.這樣就形成t1 和t2 并行執行
~~~
~~~
from threading import Thread
import time
def countdown(n):
while n > 0:
print('T-minus', n)
n -= 1
time.sleep(1)
t1 = Thread(target=countdown, args=(5,))
t2 = Thread(target=countdown, args=(2,))
t1.start()
t2.start()
打印結果:
T-minus 5
T-minus 2
T-minus 4
T-minus 1
T-minus 3
T-minus 2
T-minus 1
~~~
>[danger] ##### 構造一個線程的繼承類
~~~
1.通過繼承線程類,重寫里面的run方法,線程類中的run方法用來執行線程方法
~~~
~~~
import threading
import time
class MyTreading(threading.Thread):
def __init__(self,n):
super(MyTreading,self).__init__()
self.n = n
def run(self):
print("多線程"+self.n)
t1 = MyTreading("t1")
t2 = MyTreading("t2")
t1.start()
t2.start()
~~~
>[danger] ##### 讓類中的方法開啟線程
~~~
class CountdownTask:
def __init__(self):
self._running = True
def terminate(self):
self._running = False
def run(self, n):
while self._running and n > 0:
print('T-minus', n)
n -= 1
time.sleep(5)
c = CountdownTask()
t = Thread(target=c.run, args=(10,))
t.start()
// 線程中參數共享,所以會停止線程
c.terminate()
t.join()
~~~
>[danger] ##### 判斷線程是否運行 --- is_alive
~~~
t = Thread(target=countdown, args=(5,))
if t.is_alive():
print('Still running')
else:
print('Completed')
~~~
>[danger] ##### 設置線程守護函數 --- daemon
~~~
// true 開啟線程守護
t = Thread(target=countdown, args=(10,), daemon=True)
~~~
>[danger] ##### 計算線程運行時長 -- join
~~~
1.想知道線程時長就給知道兩個概念 --- 主線程和子線程2
2.主線程和 子線程就像打游戲, 主線任務和支線任務,主線任務就是這個程序從頭到尾執行一遍,支線任務就是你開啟的線程
~~~
* 通過例子認識主線程和子線
~~~
代碼測試run函數的運行時長
1.這段代碼的打印結果是0.0010008811950683594
2.實際我們通過嘗試推斷這個代碼運行時間應該時最后一個線程結束時間 5/10+0.1
3.為什么執行結果小于我們做的預期判斷,是因為,這個打印結果的運行時間是,主線程
4.就像打游戲我們的主線任務就是從頭跑到尾,所以這段代碼實際有 5+1個線程
~~~
~~~
import threading
import time
def run(n,m):
print("線程%s"%n)
time.sleep(m)
star_time = time.time()
# 開啟五個線程,每個線程運行時間成遞增
for i in range(5):
t1 = threading.Thread(target=run,args=(i,i/10+0.1) )
t1.start()
print('主線程')
print(float(time.time()-star_time))
~~~
* 計算線程時間運行時間 join
~~~
1.將線程連接知道最后一個線程結束才釋放,也就是線程沒有全部結束就不能往下執行
2.下面的案例只要子線程中第五個沒結束,代碼就不能往下進行,所以主線程等所有子線程結束后,在執行
~~~
~~~
import threading
import time
#創建一個保存線程的列表
list_threading = []
def run(n,m):
print("線程%s"%n)
time.sleep(m)
star_time = time.time()
for i in range(5):
t1 = threading.Thread(target=run,args=(i,i/10+0.1) )
t1.start()
list_threading.append(t1)
#循環列表執行join
for ii in list_threading:
ii.join()
print('主線程',star_time-time.time())
打印結果:
線程0
線程1
線程2
線程3
線程4
主線程 -0.5024936199188232
~~~
>[danger] ##### 打印子線程 和主線程
~~~
import threading
def run(n):
print("線程%s"%n,threading.current_thread())
for i in range(5):
t1 = threading.Thread(target=run ,args=(i,))
t1.start()
#主線程
print(threading.current_thread())
打印結果:
線程0 <Thread(Thread-1, started 9572)>
線程1 <Thread(Thread-2, started 7916)>
線程2 <Thread(Thread-3, started 4856)>
線程3 <Thread(Thread-4, started 5396)>
線程4 <Thread(Thread-5, started 9400)>
<_MainThread(MainThread, started 3360)>
~~~
>[danger] ##### 線程守護 --- daemon
~~~
1.當主線程結束后,開啟守護的線程自動結束
2.通過運行結果發現因為是個主線程開啟了守護,所以主線程結束其他線程也跟著結束
3.守護線程的生命周期在非守護線程結束時結束
~~~
* 未開啟守護線程
~~~
1.下面線程主線程結束了下面線程依舊還在執行
~~~
~~~
import threading
import time
def run(n):
print("線程%s"%n)
time.sleep(2)
print("未開啟守護打印線程%s"%n)
for i in range(4):
t1= threading.Thread(target=run,args=(i,), )
t1.start()
print("主線程")
打印結果:
線程0
線程1
線程2
線程3
主線程
未開啟守護打印線程3
未開啟守護打印線程2
未開啟守護打印線程0
未開啟守護打印線程1
~~~
* 開啟守護線程 --- daemon
~~~
import threading
import time
def run(n):
print("線程%s"%n)
time.sleep(2)
print("未開啟守護打印線程%s"%n)
for i in range(4):
t1= threading.Thread(target=run,args=(i,), daemon=True)
t1.start()
print("主線程")
打印結果:
線程0
線程1
線程2
線程3
主線程
~~~
- PYTHON-- 基礎
- Python -- 變量、常量、注解
- 算數\比較\賦值\邏輯運算符
- Python -- input 控制臺用戶輸入
- Python -- 流程控制/循環語句
- Python -- 切片
- Python -- 數據類型
- 基礎數據類型
- int -- 數字類型
- str -- 字符類型
- bool -- 布爾類型
- list -- 列表
- type -- 元祖
- dict -- 字典
- set -- 集合
- Python -- 深淺copy
- Python -- 文件的讀寫
- Python -- 函數
- 函數 -- 做參數使用
- 函數 -- 閉包
- 函數 -- 生成器
- 函數 -- 列表推導式
- 案例
- 基礎案例一
- 基礎案例二
- 基礎案例三
- COOKBOOK
- LIST、STR、DICT、TUPLE
- LIST - 列表方法總結
- 一、序列拆分成單獨變量
- 二、* 妙用
- 三、deque- 雙向隊列
- 四、求找到最大或最小的N個元素
- 4.1 heapq-- 簡單使用
- 五、去重并保持列表順序不變
- 六、切片slice
- 七、counter 統計序列中元素次數
- 八、itemgetter 列表套著字典排序
- 九、處理大量的列表數據
- 十、隨機事件處理列表
- DICT - 字典的總結方法
- 一、defaultdict 解決 KeyError
- 二、OrdereDict有序字典
- 三、zip 和 max/min 比較
- IDCT和LIST- 推導式
- 一、LIST 推導式
- 二、字典推到式
- TUPLE-元組
- 一、命名元組
- STR-字符串
- 一、常見的字符串方法
- 二、字符串拆分
- 三、字符串的位置匹配
- 四、字符串替換
- 五、正則大小寫/換行匹配
- 六、對字節類型處理
- 數字、日期、時間處理
- 一、數字的處理
- 二、時間換算
- 2.1 時間運算
- 2.2計算某一時刻上周幾的日期
- 2.2對時間轉換格式優化
- 迭代器和生成器
- 一、iter 迭代器 使用案例
- 二、生成器 yeild
- 三、構建一個反向迭代方法
- 四、實現反正函數構造
- 五、迭代對象切片/跳過元素
- 六、迭代出所有的組合排列
- 七、索引-值迭代序列化
- 八、zip 同時迭代多個序列
- 九、同時循環多個可迭代對象
- 十、yield from 遞歸案例
- 十一、合并序列,并按順序輸出
- 十二、使用 iter 替代 while True
- 操作文件
- 一、處理文件路徑
- 二、檢測文件/獲取文件信息
- 函數
- 一、函數基本案例使用
- 二、匿名函數
- 三、回調函數
- 四、閉包實現一個單個方法類
- 五、函數嵌套回調函數
- 類與對象
- 一、str/repr--讓類字符串表示
- 二、format -- 格式化類的內容
- 三、with -- 上下文管理類
- 四、創建節省內存的類
- 五、將類里面方法變成屬性
- 六、調用父類方法
- 七、擴展子類中的屬性
- 八、創建新的類或者實類屬性
- 九、簡化數據結果,簡化init
- 十、python 接口寫法
- 十一、通過類屬性創建委托訪問
- 十二、__new__重新初始化init
- 十三、通過字符串調用類
- 元編程
- 一、裝飾器
- 1.1 去掉裝飾器修飾
- 1.2 可接受參數裝飾器
- 1.3利用裝飾器對函數參數類型檢查
- 1.4編寫類裝飾器
- 1.5為類方法和靜態方法加裝飾器
- 1.6通過裝飾器給裝飾函數加參數
- 線程和進程