mirror of
https://github.com/python/cpython.git
synced 2025-11-30 06:48:54 +00:00
Added semaphores; fix event.wait().
This commit is contained in:
parent
48a69b70b2
commit
846c3224a8
1 changed files with 51 additions and 4 deletions
|
|
@ -4,6 +4,7 @@
|
||||||
# condition() # a POSIX-like condition-variable object
|
# condition() # a POSIX-like condition-variable object
|
||||||
# barrier(n) # an n-thread barrier
|
# barrier(n) # an n-thread barrier
|
||||||
# event() # an event object
|
# event() # an event object
|
||||||
|
# semaphore(n=1)# a semaphore object, with initial count n
|
||||||
#
|
#
|
||||||
# CONDITIONS
|
# CONDITIONS
|
||||||
#
|
#
|
||||||
|
|
@ -35,7 +36,7 @@
|
||||||
# threads are .wait'ing, this is a nop.
|
# threads are .wait'ing, this is a nop.
|
||||||
#
|
#
|
||||||
# Note that if a thread does a .wait *while* a signal/broadcast is
|
# Note that if a thread does a .wait *while* a signal/broadcast is
|
||||||
# in progress, it's guaranteeed to block until a subsequenct
|
# in progress, it's guaranteeed to block until a subsequent
|
||||||
# signal/broadcast.
|
# signal/broadcast.
|
||||||
#
|
#
|
||||||
# Secret feature: `broadcast' actually takes an integer argument,
|
# Secret feature: `broadcast' actually takes an integer argument,
|
||||||
|
|
@ -184,8 +185,30 @@
|
||||||
# see the event get around to .wait'ing on it. But so long as you don't
|
# see the event get around to .wait'ing on it. But so long as you don't
|
||||||
# need to .clear an event, events are easy to use safely.
|
# need to .clear an event, events are easy to use safely.
|
||||||
#
|
#
|
||||||
# Tim Peters tim@ksr.com
|
# SEMAPHORES
|
||||||
# not speaking for Kendall Square Research Corp
|
#
|
||||||
|
# A semaphore object is created via
|
||||||
|
# import this_module
|
||||||
|
# your_semaphore = this_module.semaphore(count=1)
|
||||||
|
#
|
||||||
|
# A semaphore has an integer count associated with it. The initial value
|
||||||
|
# of the count is specified by the optional argument (which defaults to
|
||||||
|
# 1) passed to the semaphore constructor.
|
||||||
|
#
|
||||||
|
# Methods:
|
||||||
|
#
|
||||||
|
# .p()
|
||||||
|
# If the semaphore's count is greater than 0, decrements the count
|
||||||
|
# by 1 and returns.
|
||||||
|
# Else if the semaphore's count is 0, blocks the calling thread
|
||||||
|
# until a subsequent .v() increases the count. When that happens,
|
||||||
|
# the count will be decremented by 1 and the calling thread resumed.
|
||||||
|
#
|
||||||
|
# .v()
|
||||||
|
# Increments the semaphore's count by 1, and wakes up a thread (if
|
||||||
|
# any) blocked by a .p(). It's an (detected) error for a .v() to
|
||||||
|
# increase the semaphore's count to a value larger than the initial
|
||||||
|
# count.
|
||||||
|
|
||||||
import thread
|
import thread
|
||||||
|
|
||||||
|
|
@ -306,10 +329,34 @@ class event:
|
||||||
|
|
||||||
def wait(self):
|
def wait(self):
|
||||||
self.posted.acquire()
|
self.posted.acquire()
|
||||||
while not self.state:
|
if not self.state:
|
||||||
self.posted.wait()
|
self.posted.wait()
|
||||||
self.posted.release()
|
self.posted.release()
|
||||||
|
|
||||||
|
class semaphore:
|
||||||
|
def __init__(self, count=1):
|
||||||
|
if count <= 0:
|
||||||
|
raise ValueError, 'semaphore count %d; must be >= 1' % count
|
||||||
|
self.count = count
|
||||||
|
self.maxcount = count
|
||||||
|
self.nonzero = condition()
|
||||||
|
|
||||||
|
def p(self):
|
||||||
|
self.nonzero.acquire()
|
||||||
|
while self.count == 0:
|
||||||
|
self.nonzero.wait()
|
||||||
|
self.count = self.count - 1
|
||||||
|
self.nonzero.release()
|
||||||
|
|
||||||
|
def v(self):
|
||||||
|
self.nonzero.acquire()
|
||||||
|
if self.count == self.maxcount:
|
||||||
|
raise ValueError, '.v() tried to raise semaphore count above ' \
|
||||||
|
'initial value ' + `maxcount`
|
||||||
|
self.count = self.count + 1
|
||||||
|
self.nonzero.signal()
|
||||||
|
self.nonzero.release()
|
||||||
|
|
||||||
# The rest of the file is a test case, that runs a number of parallelized
|
# The rest of the file is a test case, that runs a number of parallelized
|
||||||
# quicksorts in parallel. If it works, you'll get about 600 lines of
|
# quicksorts in parallel. If it works, you'll get about 600 lines of
|
||||||
# tracing output, with a line like
|
# tracing output, with a line like
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue