zoukankan      html  css  js  c++  java
  • Python进阶基础学习(多线程)

    Python进阶学习笔记(一)

    threading模块

    threading.thread(target = (函数))  负责定义子线程对象

    threading.enumerate()  负责查看子线程对象

    测试代码如下:

    import time
    import threading
    def sing():
        for i in range(5):
            print('-----唱歌-----')
            time.sleep(1)
    
    def dance():
        for i in range(5):
            print('-----跳舞-----')
            time.sleep(1)
    
    def main():
        t1 = threading.Thread(target=sing)  #子线程1
        t2 = threading.Thread(target=dance) #子线程2
        t1.start()
        t2.start()
        while True:
            print(threading.enumerate())
            if  len(threading.enumerate()) == 1:
                break
            time.sleep(1)
    if __name__ == '__main__':
        main()
    

    补充:

    线程的调度是随机的,主线程如果在子线程之前GG,你们子线程也GG

    threading.thread()不会创建线程,只有调用其实例.start()之后才会创建线程

    通过类来创建线程

    测试代码如下:

    import threading
    import time
    class Person(threading.Thread):
        def run(self) -> None:
            for i in range(3):
                print('aaa' + self.name)
                time.sleep(1)
    
    if __name__ == '__main__':
        p = Person()
        p.start()
        for i in range(3):
            print('bbb')
            time.sleep(1)
    

    补充:

    threading.thread是一个类,通过继承并且override run函数,即可声明进程

    多线程共享全局变量

    测试代码如下:

    import threading
    import time
    num = 100
    def test1():
        global num
        num += 1
        print(num)
    def test2():
        print(num)
    def main():
        t1 = threading.Thread(target=test1)
        t2 = threading.Thread(target=test2)
        t1.start()
        time.sleep(1)
        test2()
    if __name__ == '__main__':
        main()
    

    若创建线程是需要带参数,则是用args

    测试代码如下:

    num = [1,1,2,3]
    
    def test1(args):
        args.append('hhs')
        print(args)
    
    def main():
        t1 = threading.Thread(target=test1,args=(num,))
        t1.start()
        print(num)
    
    if __name__ == '__main__': 
        main()
    

    补充:args后边传的是一个元组,少了逗号会报错

    多线程共享全局变量出现的问题

    测试代码如下:

    import threading
    import time
    
    g_num = 0
    def count1(n):
        global g_num
        for i in range(n):
            g_num += 1
    
    def count2(n):
        global g_num
        for i in range(n):
            g_num += 1
    
    def main():
        t1 =threading.Thread(target=count1,args=(100000,))
        t2 = threading.Thread(target=count2, args=(100000,))
        t1.start()
        t2.start()
        time.sleep(2)
        print('正常num为200000,实际num为%d' % g_num)
    
    if __name__ == '__main__':
        main()
    

    补充:输出结果为:175586,与正常结果不相同

    解析问题:

    1.cpu是一句句执行的

    2.若把g_num += 1解析成很多句,如果线程1只执行1-2句,第三句还没赋值回去,就调用了线程2,则会出现相加的结果不等于预期的结果

    互斥锁threading.Lock()

    用于解决上面共享全局变量的问题

    变量名.acquire()  上锁

    变量名.release()  解锁

    给要执行的代码上锁,自己运行的时候别的线程无法运行

    测试代码如下:

    import threading
    import time
    
    num = 0
    mutex = threading.Lock()
    def count1(n):
        global num
        for i in range(n):
            mutex.acquire()
            num += 1
            mutex.release()
    
    def count2(n):
        global num
        for i in range(n):
            mutex.acquire()
            num += 1
            mutex.release()
    
    def main():
        t1 =threading.Thread(target=count1,args=(100000,))
        t2 = threading.Thread(target=count2, args=(100000,))
        t1.start()
        t2.start()
        time.sleep(2)
        print('正常num为200000,实际num为%d' % num)
    
    if __name__ == '__main__':
        main()
    

      

  • 相关阅读:
    洛谷P2762 太空飞行计划问题
    网络流24题 gay题报告
    洛谷P1712 区间
    洛谷P2480 古代猪文
    10.9zuoye
    面向对象类编程,计算分数
    请输入验证码优化版
    面向对象式开发程序
    直接选择排序与反转排序
    随机数产生原理
  • 原文地址:https://www.cnblogs.com/hhs1998/p/11772665.html
Copyright © 2011-2022 走看看