@@ -230,7 +230,7 @@ class XmapEndSignal():
230230 pass
231231
232232
233- def xmap_readers (mapper , reader , process_num , buffer_size ):
233+ def xmap_readers (mapper , reader , process_num , buffer_size , order = False ):
234234 """
235235 Use multiprocess to map samples from reader by a mapper defined by user.
236236 And this function contains a buffered decorator.
@@ -242,21 +242,33 @@ def xmap_readers(mapper, reader, process_num, buffer_size):
242242 :type process_num: int
243243 :param buffer_size: max buffer size
244244 :type buffer_size: int
245+ :param order: keep the order of reader
246+ :type order: bool
245247 :return: the decarated reader
246248 :rtype: callable
247249 """
248250 end = XmapEndSignal ()
249251 in_queue = Queue (buffer_size )
250252 out_queue = Queue (buffer_size )
253+ out_order = [0 ]
251254
252255 # define a worker to read samples from reader to in_queue
253256 def read_worker (reader , in_queue ):
254257 for i in reader ():
255258 in_queue .put (i )
256259 in_queue .put (end )
257260
261+ # define a worker to read samples from reader to in_queue with order flag
262+ def order_read_worker (reader , in_queue ):
263+ in_order = 0
264+ for i in reader ():
265+ in_queue .put ((in_order , i ))
266+ in_order += 1
267+ in_queue .put (end )
268+
258269 # start a read worker in a thread
259- t = Thread (target = read_worker , args = (reader , in_queue ))
270+ target = order_read_worker if order else read_worker
271+ t = Thread (target = target , args = (reader , in_queue ))
260272 t .daemon = True
261273 t .start ()
262274
@@ -271,11 +283,28 @@ def handle_worker(in_queue, out_queue, mapper):
271283 in_queue .put (end )
272284 out_queue .put (end )
273285
286+ # define a worker to handle samples from in_queue by mapper
287+ # and put mapped samples into out_queue by order
288+ def order_handle_worker (in_queue , out_queue , mapper , out_order ):
289+ ins = in_queue .get ()
290+ while not isinstance (ins , XmapEndSignal ):
291+ order , sample = ins
292+ r = mapper (sample )
293+ while order != out_order [0 ]:
294+ pass
295+ out_queue .put (r )
296+ out_order [0 ] += 1
297+ ins = in_queue .get ()
298+ in_queue .put (end )
299+ out_queue .put (end )
300+
274301 # start several handle_workers
302+ target = order_handle_worker if order else handle_worker
303+ args = (in_queue , out_queue , mapper , out_order ) if order else (
304+ in_queue , out_queue , mapper )
275305 workers = []
276306 for i in xrange (process_num ):
277- worker = Thread (
278- target = handle_worker , args = (in_queue , out_queue , mapper ))
307+ worker = Thread (target = target , args = args )
279308 worker .daemon = True
280309 workers .append (worker )
281310 for w in workers :
0 commit comments