?鎖
?使用鎖:
鎖的語法
創建鎖、鎖定鎖、釋放鎖
from
threading
import
Lock
#
創建鎖
mutex =
Lock()
#
獲取鎖(上鎖)
mutex.acquire()
#
釋放鎖(解鎖)
mutex.release()
在鎖定鎖的過程中acquire()方法可以接受一個blocking參數,
如果設定blocking為True,則當前線程會堵塞,直到獲取到這個鎖為止(如果沒有 指定,那么默認為True)?
如果設定blocking為False,則當前線程不會堵塞
?
上鎖和解鎖的過程(假設是多線程調度):
這個鎖一般是為共享資源服務的,即多個線程同時使用共享資源。這個鎖同一時間只能有一個線程調度,其他線程阻塞,只有當前調度的線程釋放這個鎖,阻塞的線程才能調度。
鎖的優點:
確保了某段關鍵代碼只能有一個線程從頭到尾完整的執行。
鎖的缺點:
組織了多線程的并發執行,包含鎖的某段代碼實際上只能以單線程模式執行,效率就大大的降低了;代碼中可能存在多個鎖,如果多個線程擁有多個鎖,容易造成死鎖。
死鎖的現象(實例):
#
死鎖 兩者都沒有釋放對方需要的鎖,而釋放的條件恰好是獲取對方釋放所需要的鎖
#
線程1
class
MyThread1(threading.Thread):
def
__init__
(self):
super().
__init__
()
def
run(self):
#
線程1獲取A鎖
if
mutexA.acquire():
print
(self.name+
"
-----do1---up-----
"
)
sleep(
1
)
#
此時線程2獲取了B鎖,需要等待線程2釋放B鎖
if
mutexB.acquire():
print
(self.name +
"
-----do1---down-----
"
)
mutexB.release()
mutexA.release()
#
線程2
class
MyThread2(threading.Thread):
def
__init__
(self):
super().
__init__
()
def
run(self):
#
線程2獲取B鎖
if
mutexB.acquire():
print
(self.name +
"
-----do2---up-----
"
)
sleep(
1
)
#
此時線程1獲取了A鎖,需要等待線程1釋放A鎖
if
mutexA.acquire():
print
(self.name +
"
-----do2---down-----
"
)
mutexA.release()
mutexB.release()
mutexA
=
threading.Lock()
mutexB
=
threading.Lock()
if
__name__
==
'
__main__
'
:
#
線程1和線程2同時執行
t1 =
MyThread1()
t2
=
MyThread2()
t1.start()
t2.start()
避免死鎖的方法:銀行家算法
多進程與多線程比較及選擇
?是否采用多任務處理,取決于我們的任務類型
?如果是計算密集型,需要大量的CPU資源進行運算,代碼的運行效率至關重 要,這樣的任務一般不使用多線程進行,因為頻繁的任務調度會拖慢CPU的
運算。
?如果是IO密集型,涉及到硬盤讀寫,網絡讀寫等的任務,更多的時間在等待 IO操作完成,這一類任務可以放到多線程或多進程中來進行。
單線程、多線程、多進程(一起實現同一代碼的時間)
#
單線程、多線程、多進程的使用及不同
#
簡單的求和
def
fib(x):
res
=
0
for
i
in
range(100000000
):
res
+= i*
x
return
res
#
階乘
def
fac(x):
if
x < 2
:
return
1
return
x*fac(x-1
)
#
簡單的求和
def
sum(x):
res
=
0
for
i
in
range(50000000
):
res
+= i*
x
return
res
#
函數列表
funcs =
[fib, fac, sum]
n
= 100
class
MyThread(threading.Thread):
def
__init__
(self, func, args, name=
""
):
super().
__init__
()
self.name
=
name
self.func
=
func
self.args
=
args
self.res
=
0
def
getResult(self):
return
self.res
def
run(self):
print
(
"
starting
"
, self.name,
"
at:
"
, ctime())
self.res
=
self.func(self.args)
print
(self.name,
"
finished at:
"
, ctime())
def
main():
nfuncs
=
range(len(funcs))
print
(
"
單線程
"
.center(30,
"
*
"
))
start
=
time()
for
i
in
nfuncs:
print
(
"
start {} at: {}
"
.format(funcs[i].
__name__
, ctime()))
start_task
=
time()
print
(funcs[i](n))
end_task
=
time()
print
(
"
任務 耗時:
"
, end_task-
start_task)
print
(
"
{} finished at: {}
"
.format(funcs[i].
__name__
, ctime()))
end
=
time()
print
(
"
單線程運行時間:
"
, end-
start)
print
(
"
單線程結束:
"
.center(30,
"
*
"
))
print
()
print
(
"
多線程
"
.center(30,
"
*
"
))
start
=
time()
threads
=
[]
for
i
in
nfuncs:
#
一個線程綁定一個函數
t = MyThread(funcs[i], n, funcs[i].
__name__
)
threads.append(t)
for
i
in
nfuncs:
#
同時啟動線程
threads[i].start()
for
i
in
nfuncs:
threads[i].join()
print
(threads[i].getResult())
end
=
time()
print
(
"
多線程運行時間:
"
, end-
start)
print
(
"
多線程結束:
"
.center(30,
"
*
"
))
print
()
print
(
"
多進程
"
.center(30,
"
*
"
))
start
=
time()
process_list
=
[]
for
i
in
nfuncs:
#
一個進程綁定一個函數
t = Process(target=funcs[i], args=
(n, ))
process_list.append(t)
for
i
in
nfuncs:
#
同時啟動進程
process_list[i].start()
for
i
in
nfuncs:
process_list[i].join()
end
=
time()
print
(
"
多進程運行時間:
"
, end -
start)
print
(
"
多進程結束:
"
.center(30,
"
*
"
))
if
__name__
==
"
__main__
"
:
main()
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

