• 线程


    1.创建线程的第一种方法(后面讲解第二种方法)

    导入:import threading

    创建一个线程的执行计划:thd=threading.Thread(target=方法名)

    启动线程:thd.start()

    例子:

    import threading
    import time
    
    def saySorry():
        print("亲爱的,我错了,我能吃饭吗?")
        time.sleep(2)
    
    if __name__ == '__main__':
        for i in range(5):
            # 创建一个线程的执行的计划
            thd=threading.Thread(target=saySorry)
    
            # 启动线程
            thd.start()

    开启线程,相当于一个进程中开启了五个分支,5个分支同时进行

    2.查看当前进程内部存活的所有线程列表

    threading.enumerate()

    3.等待子线程执行结束之后主线程才继续执行(等待子线程完成之后,继续)

    import threading
    
    def dance():
        for i in range(5):
            print("正在跳舞... %d" %i)
    
    if __name__ == '__main__':
        thd=threading.Thread(target=dance)
        thd.start()
        print("太棒了")

    执行结果:

     

    但是有时候想子线程执行完之后才让主线程继续执行

    就使用thd.join(),这个方法类似于主线程执行到这个位置,等待子线程结束才继续执行

    import threading
    
    def dance():
        for i in range(3):
            print("正在跳舞... %d" %i)
    
    if __name__ == '__main__':
        thd=threading.Thread(target=dance)
        thd.start()
    
        # 主线程阻塞等待 Thread对象标识的子线程退出之后 才会继续执行
        thd.join()
        print("太棒了")

    4.创建线程的第二种方法

    1.创建一个类,并继承Thread

    2.实现其中的run方法(run方法在Thread类中已经实现了,就相当于重写该方法,在这个run方法中就是子线程里运行的方法,相当于上面写的dance方法)

    3.创建该类的实例对象

    4.实例对象.start()启动创建和执行

    import threading
    
    class myThread(threading.Thread):
        """1. 继承Thread 2. 实现其中run方法 3. 创建该类的实例对象 4. 对象.start()启动创建和执行"""
        def run(self):
            for i in range(3):
                print("在子线程中")
    
    if __name__ == '__main__':
        mt=myThread()
        mt.start()
        print("主线程")

    5.多线程共享全局变量引起资源竞争混乱及解决方法

    比如:火车票的数量,如果同时有3个人购买火车票,而火车票的数量是100张,当第一个人购买后火车票的数量就会变成99,此时数据库就会将100这个值修改成99,而第二个人也是在这一时刻购买火车票,此时第二个人的火车票数量也是100,提交的时候就变成了99,第三个人也同样是这样(就是说这三个人在同时刻同时修改数据库里的火车票数量),假设可以提交,那么实际上火车在数据库里的数量就是99,但是已经卖出去了3张,那么就会出现数据不准的情况。这就是全局变量引起的资源竞争混乱。

    import threading
    
    # 全局变量
    g_number=0
    
    def add1():
        global g_number
        for i in range(1000000):
            g_number+=1
    
    def add2():
        global g_number
        for i in range(1000000):
            g_number+=1
    
    
    if __name__ == '__main__':
        th1=threading.Thread(target=add1)
        th1.start()
        th2=threading.Thread(target=add2)
        th2.start()
    
        th1.join()
        th2.join()
        print("结果:%d" %g_number)

    这段代码,如果按照设想结果的话:g_number的结果是2000000

    实际结果如下:

    原因就是在某一刻时间内add1,add2获取g_number的时候值相同,但是提交结果都加1,然后一个值覆盖另一个值,那么就会出现这种情况

    解决的方法:创建一个全局互斥锁,在一个线程修改这个全局变量的时候,不让别的线程修改,阻塞等待,如果修改完了,才让另一个线程修改这个全局变量值

    import threading
    
    # 全局变量
    g_number=0
    # 创建一把全局互斥锁
    g_lock=threading.Lock()
    
    def add1():
        global g_number
        for i in range(1000000):
            g_lock.acquire() # 尝试获取并且加锁,如果没有被锁定,就可以被我锁定;如果被锁定了,阻塞等待直到成功获取并锁定
            g_number+=1
            g_lock.release() # 操作完g_number变量释放锁资源,也就是解锁
    
    def add2():
        global g_number
        for i in range(1000000):
            g_lock.acquire()
            g_number+=1
            g_lock.release()
    
    
    if __name__ == '__main__':
        th1=threading.Thread(target=add1)
        th1.start()
        th2=threading.Thread(target=add2)
        th2.start()
    
        th1.join()
        th2.join()
        print("结果:%d" %g_number)

    第二种实现的方法:

    import threading
    
    # 全局变量
    g_number=0
    # 创建一把全局互斥锁
    g_lock=threading.Lock()
    
    def add1(lock):
        global g_number
        for i in range(1000000):
            lock.acquire() # 尝试获取并且加锁,如果没有被锁定,就可以被我锁定;如果被锁定了,阻塞等待直到成功获取并锁定
            g_number+=1
            lock.release() # 操作完g_number变量释放锁资源,也就是解锁
    
    def add2(lock):
        global g_number
        for i in range(1000000):
            lock.acquire()
            g_number+=1
            lock.release()
    
    
    if __name__ == '__main__':
        th1=threading.Thread(target=add1,args=(g_lock,))
        th1.start()
        th2=threading.Thread(target=add2,args=(g_lock,))
        th2.start()
    
        th1.join()
        th2.join()
        print("结果:%d" %g_number)

  • 相关阅读:
    Python脚本抓取京东手机的配置信息
    Python中的Pandas模块
    Python中的Pandas模块
    XML和JSON数据格式
    XML和JSON数据格式
    Linux运维比较常用的一些脚本
    Linux运维比较常用的一些脚本
    Keepalived高可用集群
    Keepalived高可用集群
    Linux中正则表达式和字符串的查询、替换(tr/diff/wc/find)
  • 原文地址:https://www.cnblogs.com/fjiqiang/p/10578178.html
Copyright © 2020-2023  润新知