• 多线程 threading


    Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元。

     
    import threading    #导入多线程模块
    import time
    
    def run(num):
        print ("thread..",num)
        time.sleep(1)   #休眠1秒
    
    ####单线程执行10次,需要花10秒
    for n in range(10):
        run(n)
    
    ####多线程执行10次,则花1秒
    for i in range(10):
        t = threading.Thread(target=run,args=(i,))
        t.start()
    

      

    上述代码创建了10个“前台”线程,然后控制器就交给了CPU,CPU根据指定算法进行调度,分片执行指令。

    更多方法:

    • start            线程准备就绪,等待CPU调度
    • setName      为线程设置名称
    • getName      获取线程名称
    • setDaemon   设置为后台线程或前台线程(默认)
                         如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,均停止
                          如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程也执行完成后,程序停止
    • join              逐个执行每个线程,执行完毕后继续往下执行,该方法使得多线程变得无意义
    • run              线程被cpu调度后执行Thread类对象的run方法
       

    自定义线程

    from threading import Thread
    import time
    class MyThread(Thread):     #创建一个自定义类,必须继承Thread
    def run(self):          #创建一个run函数,来优先执行父类Thread中的run
    time.sleep(1)
            print '我是线程'     #这里可以自定义加一些功能
    Thread.run(self)    #执行完后,再执行父类中的run()
    def Bar(arg):
        print 'bar',arg
    t = MyThread(target=Bar,args=(1,))
    t.start()
    print 'end..'
    

      


     

    线程锁

    由于线程之间是进行随机调度,并且每个线程可能只执行n条执行之后,CPU接着执行其他线程。所以,可能出现问题

    def run(num):
        lock.acquire()    #加锁
    print("thread...",num)
        lock.release()    #开锁
    time.sleep(1)
    lock = threading.RLock() #线程之间加一个锁,防止线程之间输出混乱
    
    for i in range(100):
        t = threading.Thread(target=run,args=(i,))
        t.start()
    

      

    Event

    python线程的事件用于主线程控制其他线程的执行,事件主要提供了三个方法 set、wait、clear。

    事件处理的机制:全局定义了一个“Flag”,如果“Flag”值为 False,那么当程序执行 event.wait 方法时就会阻塞,如果“Flag”值为True,那么event.wait 方法时便不再阻塞。

    • clear:将“Flag”设置为False
    • set:将“Flag”设置为True
    
    
    import threading
    def run(event):
        print 'start'
    event.wait()                #输出start后暂停
    print 'stop'
    event_obj = threading.Event()   #定义方法为event
    
    for i in range(10):
        t = threading.Thread(target=run,args=(event_obj,))  #循环执行run函数,参数为event_obj
    t.start()
    
    event_obj.clear()
    inp = raw_input("input:")
    if inp == "true":               #如果输入正确,则停止阻塞
    event_obj.set()
    

      

    
    
    
    

    线程池

    版本一:
    import Queue
    import threading
    import time
    
    class ThreadPool(object):   #线程池
    def __init__(self, max_num):
            self.queue = Queue.Queue(max_num)       #创建一个Queue对列,存放4个值
    for i in xrange(max_num):
                self.queue.put(threading.Thread)    #queue = 10个 threading.Thread
    def get_thread(self):
            return self.queue.get()
        def add_thread(self):
            self.queue.put(threading.Thread)
    
    pool = ThreadPool(4)       #从线程池队列拿4个值, pool=threading.Thread
    
    def func(arg, p):
        print arg
        import time
        time.sleep(5)
        p.add_thread()          #消耗掉一个线程,会执行add_thread(),往queue中添加一个 threading.Thread
        
    for i in xrange(20):             #一共执行20个进程
    thread = pool.get_thread()   # 同时4个进程,超过4个会阻塞
    t = thread(target=func, args=(i, pool))
        t.start()
    

      

    版本二:

    from Queue import Queue
    import contextlib
    import threading
      
    WorkerStop = object()
      
      
    class ThreadPool:
      
        workers = 0
      
        threadFactory = threading.Thread
        currentThread = staticmethod(threading.currentThread)
      
        def __init__(self, maxthreads=20, name=None):
      
            self.q = Queue(0)
            self.max = maxthreads
            self.name = name
            self.waiters = []
            self.working = []
      
        def start(self):
            needSize = self.q.qsize()
            while self.workers < min(self.max, needSize):
                self.startAWorker()
      
        def startAWorker(self):
            self.workers += 1
            name = "PoolThread-%s-%s" % (self.name or id(self), self.workers)
            newThread = self.threadFactory(target=self._worker, name=name)
            newThread.start()
      
        def callInThread(self, func, *args, **kw):
            self.callInThreadWithCallback(None, func, *args, **kw)
      
        def callInThreadWithCallback(self, onResult, func, *args, **kw):
            o = (func, args, kw, onResult)
            self.q.put(o)
      
      
        @contextlib.contextmanager
        def _workerState(self, stateList, workerThread):
            stateList.append(workerThread)
            try:
                yield
            finally:
                stateList.remove(workerThread)
      
        def _worker(self):
            ct = self.currentThread()
            o = self.q.get()
            while o is not WorkerStop:
                with self._workerState(self.working, ct):
                    function, args, kwargs, onResult = o
                    del o
                    try:
                        result = function(*args, **kwargs)
                        success = True
                    except:
                        success = False
                        if onResult is None:
                            pass
      
                        else:
                            pass
      
                    del function, args, kwargs
      
                    if onResult is not None:
                        try:
                            onResult(success, result)
                        except:
                            #context.call(ctx, log.err)
                            pass
      
                    del onResult, result
      
                with self._workerState(self.waiters, ct):
                    o = self.q.get()
      
        def stop(self):
            while self.workers:
                self.q.put(WorkerStop)
                self.workers -= 1
      
      
    """
    def show(arg):
        import time
        time.sleep(1)
        print arg
      
      
    pool = ThreadPool(20)
      
    for i in range(500):
        pool.callInThread(show, i)
      
    pool.start()
    pool.stop()
    """
    

      

    更多参见:twisted.python.threadpool

    上下文管理:https://docs.python.org/2/library/contextlib.html





  • 相关阅读:
    rpm命令参数(转载)
    通过KMS服务器激活windows
    icehouse版本中常用操作命令
    openstack环境搭建常用命令
    openstack 重启服务命令
    python连接mysql数据库报错pymysql连接数据库报错TypeError: __init__() takes 1 positional argument but 5 positional arguments
    Linux下LDAP统一认证解决方案
    windows系统添加IP地址黑名单
    网站防止SQL注入
    Windows服务器修改远程端口号的方法
  • 原文地址:https://www.cnblogs.com/yangmv/p/5169899.html
Copyright © 2020-2023  润新知