zoukankan      html  css  js  c++  java
  • Python基础---线程

    调用方式

    python的线程调用有两种方式。一种是直接调用,一种是继承式调用

    直接调用

    import threading,time
    
    #方法一
    def run(n):
    
        print(n)
        time.sleep(2)
    t1 = threading.Thread(target=run,args=("t1",))
    t2 = threading.Thread(target=run,args=("t2",))
    t1.start()
    t2.start()
    使用类的方法调用
    #方法二(使用类的方法)
    import threading,time
    class MyThread(threading.Thread):
        def __init__(self,n):
            super(MyThread,self).__init__()
            self.n = n
    
        def run(self):     #函数名必须为run
            print(self.n)
            time.sleep(2)
    
    t1 = MyThread(1)
    t2 = MyThread(2)
    
    t1.start()
    t2.start()


    join和Daemon

    join()等待线程结束后再往后继续运行

    Daemon()守护线程

    使用setDaemon(True)那么主线程不会等待子线程结束才结束,主线程结束后子线程也会直接结束,必须要在start之前设置否则会报错

    python中默认为setDaemon(False),主线程结束了子线程依然会执行直到完毕。

    join例子:

    import threading,time
    class MyThread(threading.Thread):
        def __init__(self,n):
            super(MyThread,self).__init__()
            self.n = n
    
        def run(self):     #函数名必须为run
            print(self.n)
            time.sleep(2)
            print('end')
    
    t1 = MyThread('t1')
    t2 = MyThread('t2')
    t1.start()
    t1.join()
    t2.start()
    t2.join()
    结果


    setDaemon()例子

    import threading,time
    class MyThread(threading.Thread):
        def __init__(self,n):
            super(MyThread,self).__init__()
            self.n = n
    
        def run(self):     #函数名必须为run
            print(self.n)
            time.sleep(2)
            print('end')
    
    t1 = MyThread('t1')
    t2 = MyThread('t2')
    t1.setDaemon(True)
    t2.setDaemon(True)
    t1.start()
    t2.start()

    结果



    线程锁

    子线程可以共享父线程的内存空间,当存在多个子线程需要同时修改一个数据的时候就可能出现问题
    假设两个子线程执行的操作都是num+1,由于线程是同时执行的,第一个子线程先取num = 1 ,第二个线程有取出num依然为1,线程一结束后num更改为2,随之线程二结束num依然被改为2,就与我们的目标出现冲突,这个时候就需要用到线程锁了,当线程一访问num的时候线程二是无法访问num的,线程一结束后释放num线程二才能访问num,这就使得num的结果不会产生冲突了。
    #线程锁示例
    import threading
    
    num = 0
    t_objs = []
    lock = threading.Lock()
    
    def run():
        lock.acquire()  #加锁
        global num      #声明全局变量
        num += 1        #执行加一操作
        lock.release()  #释放锁
    
    for i in range(500):
        t = threading.Thread(target=run)
        t.start()
        t_objs.append(t)
    
    for t in t_objs:    #等待所有线程结束
        t.join()
    
    print(num)
    递归锁则是在一个锁里面又嵌套另外一个线程锁
    #递归锁
    import threading
    
    def run1():
        lock.acquire()
        global num
        num += 1
        lock.release()
        return num
    
    def run2():
        lock.acquire()
        global num2
        num2 += 1
        lock.release()
        return num2
    
    def run3():
        lock.acquire()
        res = run1()
        res2 = run2()
        lock.release()
        print(res, res2)
    
    if __name__ == '__main__':
    
        num, num2 = 0, 0
        lock = threading.RLock()
        for i in range(10):
            t = threading.Thread(target=run3)
            t.start()
    结果


    信号量(Semaphore)

    线程锁每次只允许一个线程操作数据,Semaphore则可同时允许多个线程操作,当达到允许的最大值的时候后面的则需要等待,前面的线程执行完毕后才可执行,因此操作同一个数据的时候依然有可能出错
    #信号量
    
    import threading,time
    
    def run(num):
        semaphore.acquire()
        time.sleep(1)
        print(num)
        semaphore.release()
    
    semaphore = threading.BoundedSemaphore(3) #最多运行三个线程
    for i in range(10):
        t = threading.Thread(target=run,args=(i,))
        t.start()

    事件(Event)

    Event默认内置了一个标志,初始值为False
    event总共就四中方法:set()、clear()、wait()、is_set()
    set()设置标志位为True
    clear()设置标志位为False
    wait()等待标志位设为True
    is_set()判断标志位是否被设为True

    已红绿灯为例说明,首先写出交通灯,event.clear()相当于红灯,event.set()相当于绿灯,红灯为5秒绿灯也为5秒,用count来计数,当count超过10的时候重置count,这样红绿灯就能以5秒为间隔循环运行
    import time,threading
    
    event = threading.Event()
    
    def light():
        count = 0
        while True:
            if count >= 5 and count < 10:
                event.clear()     #相当于红灯了
                print("red light please wait...")
            elif count > 10 :
                event.set()       #相当于绿灯
                count = 0        
            else:
                print("go go go ...")
            time.sleep(1)
            count += 1
    再来写car
    def car():
        while True:
            if event.is_set():  #判断event是否被set,相当于检测是否为绿灯
                print('run...')
                time.sleep(1)
            else:
                print('waiting for green light..')
                event.wait()
                print('green light is on go...')
    运行
    l = threading.Thread(target=light)
    c = threading.Thread(target=car)
    l.start()
    c.start()
    最终的结果



    努力成为一名GEEK!
  • 相关阅读:
    CMDB表结构设计
    mysql数据库密码
    web之提取状态码
    ELK的启动脚本
    ELK的轻量级搭建使用
    liunx安装JDK
    liunx的urandom生成随机字符
    vim快捷键
    升级系统的python程序
    Mysql的进阶小记
  • 原文地址:https://www.cnblogs.com/FanMLei/p/10501032.html
Copyright © 2011-2022 走看看