来谈一谈Semaphore,它内部维护了一个计数器,每一次acquire操作都会让计数器减1,每一次release操作都会让计数器加1,当计数器为0时,任何线程的acquire操作都不会成功,Semaphore确保对资源的访问有一个上限。
如果使用Lock,RLock,那么只能有一个线程获得对资源的访问,但现实中的问题并不总是这样,假设这样一个场景,一个线程安全的操作,同一个时刻可以允许两个线程进行,如果太多了效率会降低,那么Lock,Rlock,包括Condition就不适合这种场景。
我这里举一个不恰当的例子(因为我自己没这么干过,但有助于你理解)。假设你写了一个多线程爬虫,起10个线程去爬页面,10个线程访问过于频繁了,目标网站对你采取反爬措施。但你把线程数量降到2两个就没问题了。那么对于这个场景,你仍然可以启动10个线程,只是向目标网站发送请求的这个操作,你可以用Semaphore来控制,使得同一个时刻只有两个线程在请求页面
# coding=utf-8 import <span class="wp_keywordlink_affiliate"><a href="https://www.168seo.cn/tag/threading" title="View all posts in threading" target="_blank">threading</a></span> import time semaphore = <span class="wp_keywordlink_affiliate"><a href="https://www.168seo.cn/tag/threading" title="View all posts in threading" target="_blank">threading</a></span>.Semaphore(2) def worker(id): print 'thread {id} acquire semaphore'.format(id=id) semaphore.acquire() print 'thread {id} get semaphore do something'.format(id=id) time.sleep(2) semaphore.release() print 'thread {id} release semaphore'.format(id=id) for i in range(10): t = <span class="wp_keywordlink_affiliate"><a href="https://www.168seo.cn/tag/threading" title="View all posts in threading" target="_blank">threading</a></span>.Thread(target=worker, args=(i, )) t.start()
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
# coding=utf-8
import
threading
import
time
semaphore
=
threading
.
Semaphore
(
2
)
def
worker
(
id
)
:
print
'thread {id} acquire semaphore'
.
format
(
id
=
id
)
semaphore
.
acquire
(
)
print
'thread {id} get semaphore do something'
.
format
(
id
=
id
)
time
.
sleep
(
2
)
semaphore
.
release
(
)
print
'thread {id} release semaphore'
.
format
(
id
=
id
)
for
i
in
range
(
10
)
:
t
=
threading
.
Thread
(
target
=
worker
,
args
=
(
i
,
)
)
t
.
start
(
)
|
也可以用到 比如限制数据库的链接数量
867

被折叠的 条评论
为什么被折叠?



