rosmaster threadpool.py 多线程对同一任务任务队列处理
来源:互联网 发布:机场免税店mac价格 编辑:程序博客网 时间:2024/04/29 06:10
<span style="color:#a9b7c6;"># Software License Agreement (BSD License)## Copyright (c) 2008, Willow Garage, Inc.# All rights reserved.## Redistribution and use in source and binary forms, with or without# modification, are permitted provided that the following conditions# are met:## * Redistributions of source code must retain the above copyright# notice, this list of conditions and the following disclaimer.# * Redistributions in binary form must reproduce the above# copyright notice, this list of conditions and the following# disclaimer in the documentation and/or other materials provided# with the distribution.# * Neither the name of Willow Garage, Inc. nor the names of its# contributors may be used to endorse or promote products derived# from this software without specific prior written permission.## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE# POSSIBILITY OF SUCH DAMAGE.## Revision $Id$"""Internal threadpool library for zenmaster.Adapted from U{http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/203871}Added a 'marker' to tasks so that multiple tasks with the samemarker are not executed. As we are using the thread pool for i/otasks, the marker is set to the i/o name. This prevents a slow i/ofor gobbling up all of our threads"""import threading, logging, tracebackfrom time import sleepclass MarkedThreadPool(object): """Flexible thread pool class. Creates a pool of threads, then accepts tasks that will be dispatched to the next available thread.""" def __init__(self, numThreads): """Initialize the thread pool with numThreads workers.""" self.__threads = [] self.__resizeLock = threading.Condition(threading.Lock()) self.__taskLock = threading.Condition(threading.Lock()) self.__tasks = [] self.__markers = set() self.__isJoining = False self.set_thread_count(numThreads) def set_thread_count(self, newNumThreads): """ External method to set the current pool size. Acquires the resizing lock, then calls the internal version to do real work.""" # Can't change the thread count if we're shutting down the pool! if self.__isJoining: return False self.__resizeLock.acquire() try: self.__set_thread_count_nolock(newNumThreads) finally: self.__resizeLock.release() return True def __set_thread_count_nolock(self, newNumThreads): """Set the current pool size, spawning or terminating threads if necessary. Internal use only; assumes the resizing lock is held.""" # If we need to grow the pool, do so while newNumThreads > len(self.__threads): newThread = ThreadPoolThread(self) self.__threads.append(newThread) newThread.start() # If we need to shrink the pool, do so while newNumThreads < len(self.__threads): self.__threads[0].go_away() del self.__threads[0] def get_thread_count(self): """@return: number of threads in the pool.""" self.__resizeLock.acquire() try: return len(self.__threads) finally: self.__resizeLock.release() def queue_task(self, marker, task, args=None, taskCallback=None): """Insert a task into the queue. task must be callable; args and taskCallback can be None.""" if self.__isJoining == True: return False if not callable(task): return False self.__taskLock.acquire() try: self.__tasks.append((marker, task, args, taskCallback)) return True finally: self.__taskLock.release() def remove_marker(self, marker): """Remove the marker from the currently executing tasks. Only one task with the given marker can be executed at a given time""" if marker is None: return self.__taskLock.acquire() try: self.__markers.remove(marker) finally: self.__taskLock.release() def get_next_task(self): """ Retrieve the next task from the task queue. For use only by ThreadPoolThread objects contained in the pool.""" self.__taskLock.acquire() try: retval = None for marker, task, args, callback in self.__tasks: # unmarked or not currently executing if marker is None or marker not in self.__markers: retval = (marker, task, args, callback) break if retval: # add the marker so we don't do any similar tasks self.__tasks.remove(retval) if marker is not None: self.__markers.add(marker) return retval else: return (None, None, None, None) finally: self.__taskLock.release() def join_all(self, wait_for_tasks=True, wait_for_threads=True): """ Clear the task queue and terminate all pooled threads, optionally allowing the tasks and threads to finish.""" # Mark the pool as joining to prevent any more task queueing self.__isJoining = True # Wait for tasks to finish if wait_for_tasks: while self.__tasks != []: sleep(.1) # Tell all the threads to quit self.__resizeLock.acquire() try: self.__set_thread_count_nolock(0) self.__isJoining = True # Wait until all threads have exited if wait_for_threads: for t in self.__threads: t.join() del t # Reset the pool for potential reuse self.__isJoining = False finally: self.__resizeLock.release()class ThreadPoolThread(threading.Thread): """ Pooled thread class. """ threadSleepTime = 0.1 def __init__(self, pool): """Initialize the thread and remember the pool.""" threading.Thread.__init__(self) self.setDaemon(True) # don't block program exit self.__pool = pool self.__isDying = False def run(self): """ Until told to quit, retrieve the next task and execute it, calling the callback if any. """ while self.__isDying == False: sleep(ThreadPoolThread.threadSleepTime) print("this is myt test llllllllllllllllll ") ''' </span><span style="color:#ff0000;"> marker, cmd, args, callback = self.__pool.get_next_task()#多线程对任务队列处理 </span><span style="color:#a9b7c6;"> # If there's nothing to do, just sleep a bit if cmd is None: sleep(ThreadPoolThread.threadSleepTime) else: try: try: result = cmd(*args) finally: self.__pool.remove_marker(marker) if callback is not None: callback(result) except Exception as e: logging.getLogger('rosmaster.threadpool').error(traceback.format_exc()) ''' def go_away(self): """ Exit the run loop next time through.""" self.__isDying = Trueif __name__ == '__main__': MarkedThreadPool(12) sleep(10)</span>
0 0
- rosmaster threadpool.py 多线程对同一任务任务队列处理
- 多任务处理:多线程
- java多线程处理任务
- 线程池使用ExecutorService 多线程处理队列任务
- 可伸缩多线程任务队列
- Shell模拟多线程/任务队列
- C++任务队列与多线程
- C++任务队列与多线程
- C++任务队列与多线程
- 可伸缩多线程任务队列
- 基于任务队列的多线程
- 可伸缩多线程任务队列
- C++任务队列与多线程
- C++任务队列与多线程
- 可伸缩多线程任务队列
- 多线程任务队列MulitiThreadJob实现
- C++任务队列与多线程
- C++任务队列与多线程
- android导入文件包详解
- 【程序人生】:牛人高会军
- ubuntu14.04 jdk1.7.0_79 hadoop-2.6.4 完全分布
- BZOJ 1208, 宠物收养所
- CF Gym 字符串字典序
- rosmaster threadpool.py 多线程对同一任务任务队列处理
- September English
- LAMP环境配置
- 华为29
- Memcache监控问题
- 深刻理解Python中的元类(metaclass)
- POJ_3169_Layout
- Ubuntu(Debian)的aptitude与apt-get的基本用法
- 网络超时检测-alarm()函数