forked from open-mmlab/mmdetection
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Multiprocess Queue Support MacOS (open-mmlab#33)
* Queue for Mac OS * add queue
- Loading branch information
1 parent
59ac4f3
commit 012b44c
Showing
4 changed files
with
59 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
from .files import * | ||
from .data_analyzer import * | ||
from .visualizer import * | ||
from .queue import Queue | ||
|
||
__all__ = data_analyzer.__all__ + visualizer.__all__ + files.__all__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# Adapted from: http://eli.thegreenplace.net/2012/01/04/shared-counter-with-pythons-multiprocessing/ | ||
import multiprocessing | ||
|
||
class SharedCounter(object): | ||
""" A synchronized shared counter. | ||
""" | ||
|
||
def __init__(self, n = 0): | ||
self.count = multiprocessing.Value('i', n) | ||
|
||
def increment(self, n = 1): | ||
""" Increment the counter by n (default = 1) """ | ||
with self.count.get_lock(): | ||
self.count.value += n | ||
|
||
@property | ||
def value(self): | ||
""" Return the value of the counter """ | ||
return self.count.value | ||
|
||
|
||
class Queue(multiprocessing.queues.Queue): | ||
""" A portable implementation of multiprocessing.Queue. | ||
Because of multithreading / multiprocessing semantics, Queue.qsize() may | ||
raise the NotImplementedError exception on Unix platforms like Mac OS X | ||
where sem_getvalue() is not implemented. This subclass addresses this | ||
problem by using a synchronized shared counter (initialized to zero) and | ||
increasing / decreasing its value every time the put() and get() methods | ||
are called, respectively. This not only prevents NotImplementedError from | ||
being raised, but also allows us to implement a reliable version of both | ||
qsize() and empty(). | ||
""" | ||
def __init__(self, *args, **kwargs): | ||
super(Queue, self).__init__(*args, ctx=multiprocessing.get_context(), **kwargs) | ||
self.size = SharedCounter(0) | ||
|
||
def put(self, *args, **kwargs): | ||
self.size.increment(1) | ||
super(Queue, self).put(*args, **kwargs) | ||
|
||
def get(self, *args, **kwargs): | ||
self.size.increment(-1) | ||
return super(Queue, self).get(*args, **kwargs) | ||
|
||
def qsize(self): | ||
""" Reliable implementation of multiprocessing.Queue.qsize() """ | ||
return self.size.value | ||
|
||
def empty(self): | ||
""" Reliable implementation of multiprocessing.Queue.empty() """ | ||
return not self.qsize() |