zoukankan      html  css  js  c++  java
  • Python线程操作

    一、全局锁

    1、在Python中,Python代码的执行由Python虚拟机来控制,而在Python虚拟机中,同一时刻只有一个线程在执行,就像单CPU的系统中运行多个进程那样,内存中可以存放多个程序,但在任意时刻,只有一个程序在CPU中运行。同样的,在Python解释器中可以“运行”多个线程,但在任意时刻,只有一个线程在Python解释器中运行。

    2、对Python虚拟机的访问由全局解释器锁【GIL】来控制,正是这个锁能保证同一时刻只有一个线程在运行。

    3、多线程环境中,Python虚拟机的执行方式为:

    1. 设置GIL

    2. 切换到一个线程去运行

    3. 运行:

       a. 指定数量的字节码指令,或者

       b. 线程主动让出控制(可以调用time.sleep(0)

    4. 把线程设置为睡眠状态

    5. 解锁GIL

    6. 再次重复以上所有步骤

    二、线程模块

     Python提供了【thread】和【threading】模块。在多线程编程中,建议使用【threading】模块,这是因为:

    1、在【thread】模块中,当主线程退出时,其他没有被清除的线程没有运行结束就会被退出。但在【threading】模块中能确保所有的“重要的”子线程(这里的重要的子线程指的是守护线程)运行结束后,进程才会结束

    2、在【threading】模块是更高级的线程模块,它不仅提供了Thread类,还提供了线程同步机制

    thread模块

     内建函数

    1、thread.start_new_thread(function, args[, kwargs=None])

         这个函数用来启动一个线程,其参数含义分别为:

         function:线程任务函数

         args:线程任务函数的参数【以元组的方式传入】

         kwargs:可选的参数

    2、thread.interrupt_main()

         这个函数用来中断主线程

    3、thread.exit()

         这个函数用来退出线程

    4、thread.get_ident()

         这个函数用来获取线程标识号

    5、thread.allocate_lock()

         这个线程用来获取LockType对象

    6、thread.stack_size([size])

         这个线程用来返回创建新线程栈容量,其参数含义为:

         size:指定创建新线程栈容量,该参数取值为0或不小于32,768(32KB)
    LockType对象

    1、lock.acquire([waitflag])

         这个函数用来申请锁对象,若是获得锁对象返回True,否则返回False

    2、lock.release()

         这个函数用来释放锁对象【使用该函数前提是获取锁对象】

    3、lock.locked()

         这个函数用来获取对象锁的状态,若是已被锁住则返回True,否则返回False
    示例:
    >>> import thread
    
    >>> sum = 0
    
    /*****************线程任务函数**********************/
    
    >>> def add(lock):
    
        global sum               #设置为全局变量
    
        lock.acquire()          #加锁
    
        i = 1
    
        while(i < 3):
    
            sum = sum + 10
    
            i = i + 1
    
        id = thread.get_ident() #线程号
    
        print "Thread ",id,"set sum = ",sum
    
    lock.release()          #释放锁
    
    /***********************启动线程**************************/
    
    >>> def startTask():
    
        lock = thread.allocate_lock() #申请锁对象
    
        task_0 = thread.start_new_thread(add,(lock,))
    
        task_1 = thread.start_new_thread(add,(lock,))
    
    /************************测试**************************/
    
    >>> startTask()
    
    >>> Thread  764 set sum =  20
    
    Thread  5240 set sum =  40

    threading模块

    【threading】模块式以【thread】为基础,但提供更高的线程类以及同步机制。

    内建函数

    1、threading.activeCount()

         这个函数用来获取【active Thread】的数目

    2、threading.enumerate()

         这个函数用来获取【active Thread】列表。注意:包括中断的线程以及还未开始的线程

    3、threading.currentThread()

         这个函数用来获取当前运行的【Thread object】

    4、threading.settrace(func)

         这个函数用来设置所有通过【threading】模块启动的线程的跟踪函数,该函数在【Thread Object】的【run】方法执行前被调用,其参数含义为:

         func:跟踪函数名

    5、threading.setprofile(func)

         这个函数用来设置所有通过【threading】模块启动的线程的profile函数

    6、threading.Event()

         这个工厂函数用来获取一个新的【Event Object】

    7、threading.Lock()

         这个工厂函数用来获取【LockType Object】

    8、threading.RLock()

         这个工厂函数用来获取【RLock Object】

    9、threading.Condition()

         这个工厂函数用来获取【Condition Object】

    10、threading.Semaphore([value])

         这个工厂函数用来获取【Semaphore Object】

    11、threading.BoundedSemaphore([value])

         这个工厂函数用来获取【Bounded Semaphore Object】
    内建类

    1、class threading.local

         类似Java的ThreadLocal

    2、class threading.Thread(group=None, target=None, name=None,             

                                                args=(), kwargs={})

         构造函数参数含义如下:

         target:Thread类中【run】函数调用的函数

         name:指定线程的名,默认线程名格式为:【Thread-N】

         args:target函数的参数

       1)、start()

             启动线程,值得注意的是:该方法只能被线程调用一次,否则抛出异常RuntimeError

       2)、run()

             线程任务函数。常被子类重写,类似Java Thread类的run函数

       3)、is_alive()

            判断线程是否【alive】

       4)、setDaemon()

            将线程设置为守护线程

    3、class threading.Timer(interval, function, args=[], kwargs={})

          Timer类继承threading.Thread类,其参数含义为:

          interval:线程时间执行时间间隔,以秒为单位

          function:Thread类中run函数执行的目标函数

          args:目标函数的参数

         1)、cancel()

               取消Timer任务的执行
    示例
    /***************************Timer实例************************/
    
    >>> def putOutNumber():
    
        id = threading.currentThread().getName()
    
        print id,'Hello'
    
    >>> def startTimer():
    
        timer = threading.Timer(60,putOutNumber)
    
        timer.start()
    
    >>> startTimer()
    
    >>> Thread-1 Hello
    
    /****************继承Thread与Semaphore实例********************/
    
    >>> import threading
    
    >>> class MyThread(threading.Thread):
    
        def __init__(self,name,semaphore):
    
            threading.Thread.__init__(self,None,None,name,None)
    
            self.semaphore = semaphore
    
        def run(self): #override run function
    
            self.semaphore.acquire()
    
            i = 1
    
            while(i < 3):
    
                print self.getName(),' print ',i
    
                i = i + 1
    
            self.semaphore.release()
    
     
    
    >>> def startTask():
    
        semaphore = threading.Semaphore()
    
        thread_0 = MyThread("Thread_0",semaphore)
    
        thread_1 = MyThread("Thread_1",semaphore)
    
        thread_0.start()
    
        thread_1.start()
    
     
    
    >>> startTask()
    
    >>> Thread_0  print  1
    
        Thread_0  print  2
    
        Thread_1  print  1
    
        Thread_1  print  2
    
    /*********************进程之间进行通信************************/
    
    >>> class ManagerThread(threading.Thread):
    
        def __init__(self,name,event):
    
            threading.Thread.__init__(self,None,None,name,None)
    
            self.event = event
    
        def run(self): #override run function
    
            print self.getName(),' say ','go'
    
            self.event.set()
    
    >>> class PeopleThread(threading.Thread):
    
        def __init__(self,name,event):
    
            threading.Thread.__init__(self,None,None,name,None)
    
            self.event = event
    
        def run(self):
    
            self.event.wait()
    
            print self.getName(),' start ','go'
    
     
    
    >>> def startTask():
    
        event = threading.Event()
    
        m_thread = ManagerThread("Manager",event)
    
        p_thread = PeopleThread("People",event)
    
        p_thread.start()
    
    m_thread.start()
    
    /*************************测试****************************/
    
    >>> startTask()
    
    >>> Manager  say  go
    
        People  start  go

    Mutex

    内建类

    1、class mutex.mutex

         mutex对象有两个属性:锁和队列。当锁没有被锁时,队列是空的。

        /*********************mutex Object 函数********************/

        1)、mutex.test()

              这个函数检测mutex是否被锁

         2)、 mutex.testandset()

               这个函数用来检测mutex是否被锁,若是没有锁住,则锁住并返回True,否则返回False。值得注意的是:这个函数是原子操作

         3)、mutex.lock(function, argument)

               这个函数用来执行函数function(argument)【前提是mutex没有被锁】。如果mutex锁被锁,则将function(argument)放入队列中

         4)、mutex.unlock()

              这个函数用来解锁mutex【前提是队列是空的】。如果队列不是空的,则在队列中取出第一个function(argument)执行并不解锁
    示例
    >>> import mutex
    
    >>> def putOutTask(text):
    
         print text
    
    >>> def startTask():
    
        m_metux = mutex.mutex()
    
        m_metux.lock(putOutTask,'I am task_0')
    
        m_metux.lock(putOutTask,'T am task_1')
    
        m_metux.lock(putOutTask,'I am task_2')
    
        m_metux.lock(putOutTask,'T am task_3')
    
        m_metux.lock(putOutTask,'I am task_4')
    
        m_metux.lock(putOutTask,'T am task_5')
    
        while(m_metux.test()):
    
            m_metux.unlock()
    
    m_metux.unlock()
    
    /**************************测试***************************/
    
    >>> startTask()
    
    I am task_0
    
    T am task_1
    
    I am task_2
    
    T am task_3
    
    I am task_4
    
    T am task_5
  • 相关阅读:
    laravel的验证码
    laravel的中间件
    laravel的基本使用
    laravel的路由
    layui上传文件的choose只触发一次
    宝塔访问站点上一级目录
    orcale的几个查询
    tree的递归,适合与el-tree
    GIT 命令大全
    Oracle 时间戳与日期的转换
  • 原文地址:https://www.cnblogs.com/hanfight/p/4010741.html
Copyright © 2011-2022 走看看