Python的線程之線程同步
在多線程程序中,它們互相獨(dú)立打印的時(shí)間卻是錯(cuò)亂的!
如下圖,明明t-0 > t-1 > t-2 (按照線程創(chuàng)建時(shí)間早晚排列)。最后輸出居然是t-1最落后。
我們怎么樣做避免錯(cuò)亂呢, 下面看看。
線程同步
多線程,就是多個(gè)獨(dú)立的運(yùn)行單位,同時(shí)執(zhí)行同樣的事情。
多線程不是已經(jīng)做到同時(shí)執(zhí)行了嗎?還需要同步干嘛?
是的,線程是同時(shí)被調(diào)用執(zhí)行了,但是每個(gè)線程之間互相獨(dú)立,也互相競爭了。
這就跟跑道上有3個(gè)運(yùn)動(dòng)員,槍響之后同時(shí)開跑,但是他們通常卻不是同時(shí)到達(dá)終點(diǎn)。
同步是什么意思?
同步就是原本這條跑道跑三個(gè)人的加上同步之后,在任意時(shí)間上,只有一個(gè)人在跑道。
聽起來是不是匪夷所思,怎么多線程不是為多個(gè)任務(wù)提高效率嗎?加個(gè)同步不就一個(gè)時(shí)間只有一個(gè)任務(wù)執(zhí)行了,這還扯啥多線程。
很遺憾,同步就是這個(gè)意思,我們有時(shí)會(huì)說完整一點(diǎn),同步互斥!總結(jié)來說就是:同步是一種機(jī)制,它保證跑道上面任何時(shí)候只有一個(gè)運(yùn)動(dòng)員。技術(shù)上來說就是,同步保證 程序數(shù)據(jù) 任何時(shí)候只被一個(gè)線程操作。
我們使用同步機(jī)制的時(shí)候,也是在找那些應(yīng)該被限制的'跑道‘,利用同步機(jī)制保證在那個(gè)跑道上任意時(shí)刻只有一個(gè)‘運(yùn)動(dòng)員'在上面跑步。
(解釋的很清楚了,看不懂的可以找同學(xué)討論上面的這幾句)
我們了解了同步機(jī)制,下面看看鎖。
threading.Lock獲取同步鎖
threading.Lock
是一個(gè)類,我們能用它創(chuàng)建一個(gè)鎖對象。
什么是鎖?
維持同步互斥機(jī)制的媒介
相當(dāng)于跑道有個(gè)大門,每次只開門讓一個(gè)程序員進(jìn)去跑
說錯(cuò)了,運(yùn)動(dòng)員(程序員還是需要多鍛煉?。?/p>
鎖要是壞了,后果可以自己想象(后面文章會(huì)說)。
我們下面代碼會(huì)用到Lock的兩個(gè)函數(shù):
acquire函數(shù):獲取鎖
release函數(shù):釋放鎖
前文說過了,加上主線程,一共是4個(gè)線程。
運(yùn)行下面代碼看看:
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2021/11/21 12:02 上午 # @Author : LeiXueWei # @CSDN/Juejin/Wechat: 雷學(xué)委 # @XueWeiTag: CodingDemo # @File : __init__.py.py # @Project : hello import threading import datetime import time def dianzan_guanzhu(lock: threading.Lock): thread_name = threading.current_thread().getName() print("線程啟動(dòng)了:", thread_name) now = datetime.datetime.now() name = "python萌新" + thread_name lock.acquire() print("%s - %s name:%s" % (thread_name, now, name)) time.sleep(1) result = "好棒!" + name + " 關(guān)注雷學(xué)委,學(xué)會(huì)了開發(fā)知識!" print("%s - %s result:%s" % (thread_name, now, result)) lock.release() return result my_lock = threading.Lock() for i in range(3): mythread = threading.Thread(name="t-" + str(i), target=lambda: dianzan_guanzhu(my_lock)) print("mythread:", mythread) print("is_alive:", mythread.is_alive()) mythread.start() ac = threading.active_count() print("active_count:", ac)
下面是運(yùn)行結(jié)果:
我們看到每個(gè)線程都完整完成了任務(wù),不會(huì)出現(xiàn)三個(gè)線程互相穿插錯(cuò)亂的輸出。
這里初學(xué)者可以感受一下同步的作用,效果。
總結(jié)
以上就是一種線程協(xié)調(diào)方案。
線程同步,也并非同一步調(diào),而是同步互斥!
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
python中g(shù)etattr函數(shù)使用方法 getattr實(shí)現(xiàn)工廠模式
這篇文章主要介紹了python中g(shù)etattr()這個(gè)函數(shù)的一些用法,大家參考使用吧2014-01-01python中實(shí)現(xiàn)迭代器(iterator)的方法示例
我們經(jīng)常需要遍歷一個(gè)對象中的元素,在Python中這種功能是通過迭代器來實(shí)現(xiàn)的。下面這篇文章主要給大家介紹了python中實(shí)現(xiàn)迭代器(iterator)的方法示例,需要的朋友可以參考借鑒,下面來一起看看吧。2017-01-01python函數(shù)裝飾器構(gòu)造和參數(shù)傳遞
這篇文章主要介紹了python函數(shù)裝飾器構(gòu)造和參數(shù)傳遞,下面通過一個(gè)小案例來簡單的理解什么是裝飾器,需要的小伙伴可以參考一下2022-03-03Python使用urllib2獲取網(wǎng)絡(luò)資源實(shí)例講解
urllib2是Python的一個(gè)獲取URLs(Uniform Resource Locators)的組件。他以urlopen函數(shù)的形式提供了一個(gè)非常簡單的接口,下面我們用實(shí)例講解他的使用方法2013-12-12Python中的數(shù)字類型與轉(zhuǎn)換技巧示例講解
這篇文章主要為大家介紹了Python中的數(shù)字類型與轉(zhuǎn)換技巧示例講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09詳解使用python的logging模塊在stdout輸出的兩種方法
這篇文章主要介紹了詳解使用python的logging模塊在stdout輸出的相關(guān)資料,需要的朋友可以參考下2017-05-05Pycharm創(chuàng)建項(xiàng)目時(shí)如何自動(dòng)添加頭部信息
這篇文章主要介紹了Pycharm創(chuàng)建項(xiàng)目時(shí) 自動(dòng)添加頭部信息,需要的朋友可以參考下2019-11-11