zoukankan      html  css  js  c++  java
  • Python线程问题

    目录

    线程

    什么是线程

    • 是系统分配给处理器时间资源的基本单位,或者说进程之内独立执行的一个单元执行流

    特点

    • 程序执行的最小单位

    为什么需要线程

    1. 进程在同一时段只能做一件事情,如果想做很多事情,就会有些困难
    2. 进程在执行中遭遇阻塞,那么整个进程就会挂起

    如何开启线程

    #方式一
    from threading import Thread
    import time
    
    ###线程开启的第一种方式
    def mythred():
        print('线程开启')
        time.sleep(5)
        print('线程结束')
    #线程中可加可不加
    if __name__ == '__main__':
        t = Thread(target = mythred)
        t.start()
    
    
    #####方式二
    from threading import Thread
    import time
    #通过类继承额方法
    class Mythred(Thread):
        def run(self):
            print('线程开启')
            time.sleep(5)
            print('线程结束')
    
    t = Mythred()
    t.start()
    

    线程创建速度vs进程创建速度

    from threading import Thread
    from multiprocessing import Process
    import time
    
    def task(name):
        print(f'{name} is running')
        time.sleep(2)
        print(f'{name} is end')
    
    
    if __name__ == '__main__':
        t = Thread(target=task,args=('子线程',))
        p = Process(target=task,args=('子进程',))
        # t.start()
        p.start()
        print('主')
    
    '''
    开启子线程的打印效果:
    
    子线程 is running
    主
    子线程 is end
    
    开启子进程打印效果:
    
    主
    子进程 is running
    子进程 is end
    
    进程和线程的创建速度
    开启子进程需要申请资源开辟空间 慢
    开启子线程只是告诉操作系统一个执行方案 快
    '''
    

    线程的join方法

    线程的join方法使用起来与进程的join方法相同

    from threading import Thread
    import time
    def task():
        print('子线程 start')
        time.sleep(2)
        print('子线程 end')
    
    t = Thread(target=task)
    t.start()
    t.join() # 等待子线程运行结束
    print('主线程')
    

    守护线程

    # 守护线程 守护的是进程的运行周期
    from threading import Thread,enumerate,currentThread
    import time
    
    def task():
        print('守护线程开始')
        print(currentThread())
        time.sleep(20)
        # print('守护线程结束')
    
    def task2():
        print('子线程 start')
        time.sleep(5)
        print(enumerate())
        print('子线程 end')
    
    if __name__ == '__main__':
        t1 = Thread(target=task)
        t2 = Thread(target=task2)
        t1.daemon = True
        t2.start()
        t1.start()
        print('主')
    

    线程锁的安全问题

    from threading import Thread,Lock
    
    x = 0
    def task():
        global x
        for i in range(100000):
            x += 1
    
    
    t1 = Thread(target=task)
    t2 = Thread(target=task)
    t3 = Thread(target=task)
    t1.start()
    t2.start()
    t3.start()
    
    print(x)
    

    228891

    上述代码我们发现,本应该为300000的x值发生了偏差。

    解决方法
    from threading import Thread,Lock
    
    x = 0
    lock = Lock()
    def task():
        global x
        lock.acquire()
        for i in range(200000):
            x += 1
        lock.release()
    
    t1 = Thread(target=task)
    t2 = Thread(target=task)
    t3 = Thread(target=task)
    t1.start()
    t2.start()
    t3.start()
    t1.join()
    t2.join()
    t3.join()
    print(x)
    

    线程死锁问题

    所谓死锁

    • 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程
    from threading import Thread,Lock
    lock1 = Lock()
    lock2 = Lock()
    import time
    class Mythread(Thread):
        def run(self):
            self.task1()
            self.task2()
        def task1(self):
            lock1.acquire()
            print(f'{self.name}抢到了锁一')
            lock2.acquire()
            print(f'{self.name}抢到了锁二')
            lock2.release()
            print(f'{self.name}释放掉了锁二')
            lock1.release()
            print(f'{self.name}释放掉了锁一')
    
        def task2(self):
            lock2.acquire()
            print(f'{self.name}抢到了锁二')
    
    
    for i in range(3):
        t = Mythread()
        t.start()
    

    递归锁(用于解决死锁问题)

    from threading import Thread,Lock,RLock
    # 递归锁 在同一个线程内可以被多次acquire
    # 如何释放 内部相当于维护了一个计数器 也就是说同一个线程 acquire了几次就要release几次
    mutex1 = RLock()
    mutex2 = mutex1
    import time
    class MyThreada(Thread):
        def run(self):
            self.task1()
            self.task2()
        def task1(self):
            mutex1.acquire()
            print(f'{self.name} 抢到了 锁1 ')
            print(f'{self.name} 释放了 锁1 ')
    
        def task2(self):
            mutex1.acquire()
            print(f'{self.name} 抢到了 锁1 ')
            mutex1.release()
            print(f'{self.name} 释放了 锁1 ')
    
    for i in range(3):
        t = MyThreada()
        t.start()
    

    信号量

    含义:
    • 一个进程向另一个进程发送一个信号来传递某种信息,接收者根据接收到的信号进行相应的行为

    使用threading模块里的Semaphore类实现了信号量对象

    from threading import Thread,currentThread,Semaphore
    import time
    
    def task():
        sm.acquire()
        print(f'{currentThread().name} 在执行')
        time.sleep(3)
        sm.release()
    
    sm = Semaphore(5)
    for i in range(15):
        t = Thread(target=task)
        t.start()
    
    
  • 相关阅读:
    Thymeleaf踩坑:[[ 和 ]] 被当做表达式解析,但是想要的就是数组,怎么办?
    RoamEdit 邀请码
    python:新版xlrd报 Excel xlsx file; not supported
    JavaFX学习:快捷键
    JavaFX学习:键盘事件
    JavaFX学习:连续点击事件
    JavaFX学习:Button基本使用
    (转)IDEA 更新插件时报错 SSL error probably caused by disabled SNI
    TextControl技术互助
    一个简单的Webservice的demo(中)_前端页面调用
  • 原文地址:https://www.cnblogs.com/ledgua/p/11543917.html
Copyright © 2011-2022 走看看