python多線程深入理解
- 低級接口
- 基本使用
- Event
- Semaphore
- 線程通信
- 高級接口
低級接口
基本使用
join()方法用來阻塞主線程??梢宰⑨尩?、看看打印順序。
import
threading
import
time
def
test
(
n
)
:
time
.
sleep
(
1
)
print
(
n
)
t
=
threading
.
Thread
(
target
=
test
,
args
=
(
7
,
)
)
t
.
start
(
)
t
.
join
(
)
# 等待子線程執行完畢,才繼續執行主線程。
print
(
'主線程執行完畢'
)
Event
當
Event
被激活時候,所有等待
Event
的線程將全部激活!
event.set()
用來激活,
event.wait()
等待事件發生。
import
threading
import
time
def
produce
(
n
,
ee
)
:
time
.
sleep
(
1
)
print
(
n
)
print
(
'go !!!'
)
ee
.
set
(
)
def
consumer
(
n
,
ee
)
:
print
(
'wait'
)
ee
.
wait
(
)
print
(
f
'{n} running......'
)
ee
=
threading
.
Event
(
)
m
=
threading
.
Thread
(
target
=
produce
,
args
=
(
0
,
ee
)
)
t
=
threading
.
Thread
(
target
=
consumer
,
args
=
(
1
,
ee
)
)
t
.
start
(
)
# m.start()
Semaphore
當信號量被釋放,其他線程才能競爭這個信號量。
只有當線程通過競爭 獲取到這個信號量,才能繼續執行程序。
from
threading
import
Semaphore
,
Thread
from
time
import
sleep
def
worker
(
n
,
sema
)
:
sema
.
acquire
(
)
sleep
(
1
)
print
(
n
)
# breakpoint()
sema
.
release
(
)
sema
=
Semaphore
(
5
)
for
i
in
range
(
10
)
:
t
=
Thread
(
target
=
worker
,
args
=
(
i
,
sema
)
)
t
.
start
(
)
線程通信
使用queue即可。用put()方法入隊,get()方法獲取隊列元素。
from
queue
import
Queue
import
threading
import
time
def
producer
(
q
)
:
while
True
:
time
.
sleep
(
5
)
q
.
put
(
'apple'
)
def
consumer
(
q
)
:
while
True
:
print
(
f
'eat {q.get()}'
)
if
__name__
==
'__main__'
:
q
=
Queue
(
maxsize
=
5
)
for
i
in
range
(
10
)
:
t1
=
threading
.
Thread
(
target
=
producer
,
args
=
(
q
,
)
)
t1
.
start
(
)
t2
=
threading
.
Thread
(
target
=
consumer
,
args
=
(
q
,
)
)
t2
.
start
(
)
高級接口
請參考concurrent.futures模塊
參考寫法一(submit()):
from
concurrent
.
futures
import
ThreadPoolExecutor
,
ProcessPoolExecutor
,
as_completed
import
time
,
random
def
mytimeit
(
f
)
:
def
ret
(
)
:
start_time
=
time
.
time
(
)
f
(
)
end_time
=
time
.
time
(
)
print
(
'timeit : '
,
end_time
-
start_time
)
return
ret
def
ppow
(
a
,
b
)
:
time
.
sleep
(
1
)
return
pow
(
a
,
b
)
@mytimeit
def
run
(
)
:
with
ThreadPoolExecutor
(
max_workers
=
1000
)
as
executor
:
all_tasks
=
{
executor
.
submit
(
ppow
,
2
,
j
)
:
j
for
j
in
range
(
10000
)
}
for
task
in
as_completed
(
all_tasks
)
:
print
(
task
.
result
(
)
,
all_tasks
[
task
]
)
if
__name__
==
"__main__"
:
run
(
)
參考寫法二(map()):
# python3.7
# 更新pip安裝的模塊(多進程)
# 想用多線程,只需要把文件里的ProcessPoolExecutor全部替換成ThreadPoolExecutor即可
import
subprocess
from
concurrent
.
futures
import
ProcessPoolExecutor
res
=
subprocess
.
run
(
'pip list -o'
,
capture_output
=
True
,
text
=
True
)
# 獲取需要更新的模塊
need_update
=
[
item
.
split
(
' '
)
[
0
]
for
item
in
res
.
stdout
.
split
(
'\n'
)
[
2
:
]
]
with
ProcessPoolExecutor
(
max_workers
=
100
)
as
exe
:
exe
.
map
(
subprocess
.
run
,
[
f
'pip install -U {name}'
for
name
in
need_update
if
name
]
)
上面這個可能無法運行
import
subprocess
from
concurrent
.
futures
import
ProcessPoolExecutor
res
=
subprocess
.
run
(
'pip list -o -i https://mirrors.aliyun.com/pypi/simple'
.
split
(
)
,
stdout
=
subprocess
.
PIPE
)
# 獲取需要更新的模塊
need_update
=
[
item
.
split
(
' '
)
[
0
]
for
item
in
str
(
res
)
.
split
(
'\\n'
)
[
2
:
]
]
print
(
need_update
)
with
ProcessPoolExecutor
(
max_workers
=
100
)
as
exe
:
exe
.
map
(
subprocess
.
run
,
[
'pip install -i https://mirrors.aliyun.com/pypi/simple -U {}'
.
format
(
name
)
.
split
(
)
for
name
in
need_update
if
name
]
)
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
