demo
import threading
import time
g_num = 0
def fun_add_01(num):
global g_num
for i in range(num):
g_num += 1
print(g_num)
def fun_add_02(num):
global g_num
for i in range(num):
g_num += 1
print(g_num)
def main():
func_01 = threading.thread(target=fun_add_01,args=(1000000,))
func_02 = threading.thread(target=fun_add_02, args=(1000000,))
func_01.start()
func_02.start()
time.sleep(5)
print(g_num)
if __name__ == '__main__':
main()
輸出結果
1130716
1262620
1262620
解析:
上述問題的產生主要是由兩個函式中g_num += 1產生,g_num += 1在執行可以分為三步,
第一步:獲取g_num的值
第二步: 讓g_num加1
第三步:儲存g_num的值
在多執行緒中,由於執行緒之間的來回切換,第乙個函式中執行完第二步,還沒儲存到g_num中,執行緒切換到第二個函式中,此時函式1完成了加1的動作,但g_num傳到第二個函式中的值卻是沒有發生變化的,此時在函式2中繼續進行上述操作,當函式2可能完成加1的動作後再次切換到函式1,此時函式1的+1值才會計入到g_num中。由於兩個函式不斷切換導致許多+1的動作完成後,其值並未計入到記憶體中,最後導致結果出錯
解決方法:
使用互斥鎖,互斥鎖裡面的**在執行的時候,程序不會切換
互斥鎖使用
mutex = threading.lock()
mutex.acquire()
# 執行**
mutex.release()
死鎖的產生
mutex1 = threading.lock()
mutex2 = threading.lock()
執行緒1mutex1.acquire()
mutex2.acquire()
# 執行**
mutex2.release()
mutex1.release()
執行緒2mutex2.acquire()
mutex1.acquire()
# 執行**
mutex1.release()
mutex2.release()
此時,鎖1等待鎖2解開,鎖2等待鎖1解開,最終造成了堵塞
避免死鎖的方法
1 設定超時時間
2 銀行家演算法
多執行緒 避免多執行緒競爭
不可修改變數 互斥鎖cas 返回狀態碼 https是http加上ssl的應用層協議。在http的基礎上增加了安全性和可靠性。埠的不同 http預設是80埠,https預設是443埠 安全性 http是明文傳輸,https是密文傳輸。認證 http沒有認證,https在建立tcp連線前會進行ssl層的...
作業系統之多執行緒資源競爭篇
互斥 概念 對於臨界資源區,同一時刻只能有乙個執行緒來訪問,其他執行緒被阻止進入臨界資源區。同步 概念 併發執行緒在一些關鍵點上可能需要互相等待與互通訊息,這種相互等待與互通訊息稱為執行緒同步。那麼問題來了,作業系統是如何實現互斥與同步的?主要的方法有2種 鎖和訊號量其中,鎖和訊號量都能實現執行緒間...
多執行緒競爭問題分析
public class mystack public synchronized string pop throws interruptedexception return list remove list size 1 問題 這段 大多數情況下執行正常,但是某些情況下會出問題。什麼時候會出現什麼問...