網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
線程的創(chuàng)建與使用
在Python中有很多的多線程模塊,其中?thread
ing 模塊就是比較常用的。下面就來看一下如何利用?thread
ing 創(chuàng)建線程以及它的常用方法。
線程的創(chuàng)建 -threading
函數(shù)名 | 介紹 | 舉例 |
---|---|---|
Thread | 創(chuàng)建線程 | Thread(target, args) |
Thread 的動(dòng)能介紹:通過調(diào)用 threading 模塊的 Thread 類來實(shí)例化一個(gè)線程對(duì)象;它有兩個(gè)參數(shù): target 與 args (與創(chuàng)建進(jìn)程時(shí),參數(shù)相同)。target 為創(chuàng)建線程時(shí)要執(zhí)行的函數(shù),而 args 為是要執(zhí)行這個(gè)函數(shù)時(shí)需要傳入的參數(shù)。
線程對(duì)象的常用方法
接下里看一下線程對(duì)象中都有哪些常用的方法:
函數(shù)名 | 介紹 | 用法 |
---|---|---|
start | 啟動(dòng)線程 | start() |
join | 阻塞線程直到線程執(zhí)行結(jié)束 | join(timeout=None) |
getName | 獲取線程的名字 | getName() |
setName | 設(shè)置線程的名字 | setName(name) |
is_alive | 判斷線程是否存活 | is_alive() |
setDaemon | 守護(hù)線程 | setDaemon(True) |
- start 函數(shù):?jiǎn)?dòng)一個(gè)線程;沒有任何返回值和參數(shù)。
- join 函數(shù):和進(jìn)程中的 join 函數(shù)一樣;阻塞當(dāng)前的程序,主線程的任務(wù)需要等待當(dāng)前子線程的任務(wù)結(jié)束后才可以繼續(xù)執(zhí)行;參數(shù)為
- timeout:代表阻塞的超時(shí)時(shí)間。
- getName 函數(shù):獲取當(dāng)前線程的名字。
- setName 函數(shù):給當(dāng)前的線程設(shè)置名字;參數(shù)為 name:是一個(gè)字符串類型
- is_alive 函數(shù):判斷當(dāng)前線程的狀態(tài)是否存貨
- setDaemon 函數(shù):它是一個(gè)守護(hù)線程;如果腳本任務(wù)執(zhí)行完成之后,即便進(jìn)程池還沒有執(zhí)行完成業(yè)務(wù)也會(huì)被強(qiáng)行終止。子線程也是如此,如果希望主進(jìn)程或者是主線程先執(zhí)行完自己的業(yè)務(wù)之后,依然允許子線程繼續(xù)工作而不是強(qiáng)行關(guān)閉它們,只需要設(shè)置 setDaemon() 為 True 就可以了。
PS:通過上面的介紹,會(huì)發(fā)現(xiàn)其實(shí)線程對(duì)象里面的函數(shù)幾乎和進(jìn)程對(duì)象中的函數(shù)非常相似,它們的使用方法和使用場(chǎng)景幾乎是相同的。
線程演示案例
單線程初始案例
演示 多線程之前 先看一下下面這個(gè)案例,運(yùn)行結(jié)束后看看共計(jì)耗時(shí)多久
1、定義一個(gè)列表,里面寫一些內(nèi)容。
2、再定義一個(gè)新列表,將上一個(gè)列表的內(nèi)容隨機(jī)寫入到新列表中;并且刪除上一個(gè)列表中隨機(jī)獲取到的內(nèi)容。
3、這里需要使用到 r andom 內(nèi)置模塊
代碼示例如下:
# coding:utf-8 import time import random old_lists = ['羅馬假日', '怦然心動(dòng)', '時(shí)空戀旅人', '天使愛美麗', '天使之城', '倒霉愛神', '愛樂之城'] new_lists = [] def work(): if len(old_lists) == 0: # 判斷 old_list 的長(zhǎng)度,如果為0 ,則表示 該列表的內(nèi)容已經(jīng)被刪光了 return '\'old_list\' 列表內(nèi)容已經(jīng)全部刪除' old_choice_data = random.choice(old_lists) # random 模塊的 choice函數(shù)可以隨機(jī)獲取傳入的 old_list 的元素 old_lists.remove(old_choice_data) # 當(dāng)獲取到這個(gè)隨機(jī)元素之后,將該元素從 old_lists 中刪除 new_choice_data = '%s_new' % old_choice_data # 將隨機(jī)獲取到的隨機(jī)元素通過格式化方式重新賦值,區(qū)別于之前的元素 new_lists.append(new_choice_data) # 將格式化的新的隨機(jī)元素添加至 new_lists 列表 time.sleep(1) if __name__ == '__main__': strat_time = time.time() for i in range(len(old_lists)): work() if len(old_lists) ==0: print('\'old_lists\' 當(dāng)前為:{}'.format(None)) else: print(('\'old_lists\' 當(dāng)前為:{}'.format(old_lists))) if not len(new_lists) == 0: print(('\'new_lists\' 當(dāng)前為:{}'.format(new_lists))) else: print('\'new_lists\' 當(dāng)前為:{}'.format(None)) end_time = time.time() print('運(yùn)行結(jié)束,累計(jì)耗時(shí):{} 秒'.format(end_time - strat_time))
運(yùn)行結(jié)果如下:
從運(yùn)行輸出結(jié)果我們可以看到整個(gè)腳本運(yùn)行共計(jì)耗時(shí)7秒,而且 new_lists 列表內(nèi)的元素都經(jīng)過格式化處理后加上了 _new ;不僅如此, 因?yàn)?random模塊的choice函數(shù) 原因,new_lists 的內(nèi)容順序與 old_lists 也是不一樣;每次運(yùn)行順序都會(huì)不一樣,所以 old_lists 的順序是無(wú)法得到保障的。
多線程演示案例
代碼示例如下:
# coding:utf-8 import time import random import threading old_lists = ['羅馬假日', '怦然心動(dòng)', '時(shí)空戀旅人', '天使愛美麗', '天使之城', '倒霉愛神', '愛樂之城'] new_lists = [] def work(): if len(old_lists) == 0: # 判斷 old_list 的長(zhǎng)度,如果為0 ,則表示 該列表的內(nèi)容已經(jīng)被刪光了 return '\'old_list\' 列表內(nèi)容已經(jīng)全部刪除' old_choice_data = random.choice(old_lists) # random 模塊的 choice函數(shù)可以隨機(jī)獲取傳入的 old_list 的元素 old_lists.remove(old_choice_data) # 當(dāng)獲取到這個(gè)隨機(jī)元素之后,將該元素從 old_lists 中刪除 new_choice_data = '%s_new' % old_choice_data # 將隨機(jī)獲取到的隨機(jī)元素通過格式化方式重新賦值,區(qū)別于之前的元素 new_lists.append(new_choice_data) # 將格式化的新的隨機(jī)元素添加至 new_lists 列表 time.sleep(1) if __name__ == '__main__': strat_time = time.time() print('\'old_lists\'初始長(zhǎng)度為:{}'.format(len(old_lists))) # 獲取 old_lists 與 new_lists 最初始的長(zhǎng)度 print('\'new_lists\'初始長(zhǎng)度為:{}'.format(len(new_lists))) thread_list = [] # 定義一個(gè)空的 thread_list 對(duì)象,用以下方添加每個(gè)線程 for i in range(len(old_lists)): thread_work = threading.Thread(target=work) # 定義一個(gè)線程實(shí)例化對(duì)象執(zhí)行 work 函數(shù),因?yàn)?work 函數(shù)沒有參數(shù)所以不用傳 args thread_list.append(thread_work) # 將 thread_work 添加進(jìn) thread_list thread_work.start() # 啟動(dòng)每一個(gè)線程 for t in thread_list: # 通過for循環(huán)將每一個(gè)線程進(jìn)行阻塞 t.join() if len(old_lists) ==0: print('\'old_lists\' 當(dāng)前為:{}'.format(None), '當(dāng)前長(zhǎng)度為:{}'.format(len(old_lists))) else: print(('\'old_lists\' 當(dāng)前為:{}'.format(old_lists))) if not len(new_lists) == 0: print('\'new_lists\' 當(dāng)前長(zhǎng)度為:{}'.format(len(new_lists))) print('\'new_lists\' 當(dāng)前的值為:{}'.format(new_lists)) else: print('\'new_lists\' 當(dāng)前為:{}'.format(None)) end_time = time.time() print('運(yùn)行結(jié)束,累計(jì)耗時(shí):{} 秒'.format(end_time - strat_time))
運(yùn)行結(jié)果如下:
從運(yùn)行的結(jié)果來看,我們初始的單線程任務(wù)耗時(shí)為 7秒,在使用多線程之后,僅耗時(shí) 1秒就完成了,大大的提高了我們的運(yùn)行效率。
線程的問題
通過上面的練習(xí),我們發(fā)現(xiàn)進(jìn)程的使用方法幾乎與進(jìn)程是一模一樣的。它們都可以互不干擾的執(zhí)行程序,也可以使得主線程的程序不需要等待子線程的任務(wù)完成之后再去執(zhí)行。只不過剛剛的演示案例中我們使用了 join() 函數(shù)進(jìn)行了阻塞,這里可以吧 join() 去掉,看看執(zhí)行效果。
與進(jìn)程一樣,線程也存在著一定的問題。
線程執(zhí)行的函數(shù),也同樣是無(wú)法獲取返回值的。
當(dāng)多個(gè)線程同時(shí)修改文件一樣會(huì)造成被修改文件的數(shù)據(jù)錯(cuò)亂的錯(cuò)誤(因?yàn)槎际遣l(fā)去操作一個(gè)文件,特別是在處理交易場(chǎng)景的時(shí)候,需要尤為注意)。
原文鏈接:https://blog.csdn.net/weixin_42250835/article/details/124105655
相關(guān)推薦
- 2023-07-24 uniapp開發(fā) h5和小程序 拖動(dòng)懸浮按鈕
- 2023-12-23 css設(shè)置文字超出顯示...
- 2022-11-13 Python中np.random.randint()參數(shù)詳解及用法實(shí)例_python
- 2022-12-10 深入分析React源碼中的合成事件_React
- 2022-07-14 Android實(shí)現(xiàn)多點(diǎn)觸摸操作_Android
- 2022-08-21 android實(shí)現(xiàn)可以滑動(dòng)的平滑曲線圖_Android
- 2023-03-21 Python代碼模擬CPU工作原理_python
- 2022-07-20 如何go語(yǔ)言比較兩個(gè)對(duì)象是否深度相同_Golang
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支