• 21天学Python --- 打卡5:Python && Threading


    在这里插入图片描述

    21天学Python --- 打卡5:Python && Threading


    在这里插入图片描述

    文章摘抄笨小孩: https://blog.csdn.net/weixin_40481076/article/details/101594705.

    1.Threading

    1.1 什么是线程

    • 线程也叫轻量级进程,是操作系统能够进行运算调度的最小单位,它被包涵在进程之中,是进程中的实际运作单位。线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其他线程共享进程所拥有的全部资源。一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行

    1.2 两者的区别

    线程与进程的区别:

    • 线程共享内存,进程独立内存
    • 线程启动速度块,进程启动速度慢,运行时速度没有可比性
    • 同一个进程的线程间可以直接交流,两个进程想通信,必须通过一个中间代理来实现
    • 创建新线程很简单,创建新进程需要对其父进程进行一次克隆
    • 一个线程可以控制和操作同一线程里的其他线程,但是进程只能操作子进程

    2.创建线程

    python主要是通过thread和threading这两个模块来实现多线程支持。python的thread模块是比较底层的模块,python的threading模块是对thread做了一些封装

    2.1 普通创建

    def run(n):
        print('task',n)
        time.sleep(1)
        print('2s')
        time.sleep(1)
        print('1s')
        time.sleep(1)
        print('0s')
        time.sleep(1)
    
    if __name__ == '__main__':
        t1 = threading.Thread(target=run,args=('t1',))     # target是要执行的函数名(不是函数),args是函数对应的参数
        t2 = threading.Thread(target=run,args=('t2',))
        t1.start()
        t2.start()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2.2 自定义

    class MyThread(threading.Thread):
        def __init__(self,n):
            super(MyThread,self).__init__()   #重构run函数必须写
            self.n = n
    
        def run(self):
            print('task',self.n)
            time.sleep(1)
            print('2s')
            time.sleep(1)
            print('1s')
            time.sleep(1)
            print('0s')
            time.sleep(1)
    
    if __name__ == '__main__':
        t1 = MyThread('t1')
        t2 = MyThread('t2')
        t1.start()
        t2.start()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    2.3 守护线程

    def run(n):
        print('task',n)
        time.sleep(1)
        print('3s')
        time.sleep(1)
        print('2s')
        time.sleep(1)
        print('1s')
    
    if __name__ == '__main__':
        t=threading.Thread(target=run,args=('t1',))
        t.setDaemon(True)
        t.start()
        print('end')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2.4 多线程共享全局变量

    g_num = 100
    def work1():
        global  g_num
        for i in range(3):
            g_num+=1
        print('in work1 g_num is : %d' % g_num)
    
    def work2():
        global g_num
        print('in work2 g_num is : %d' % g_num)
    
    if __name__ == '__main__':
        t1 = threading.Thread(target=work1)
        t1.start()
        time.sleep(1)
        t2=threading.Thread(target=work2)
        t2.start()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    2.5 主线程等待子线程结束

    def run(n):
        print('task',n)
        time.sleep(2)
        print('5s')
        time.sleep(2)
        print('3s')
        time.sleep(2)
        print('1s')
    if __name__ == '__main__':
        t=threading.Thread(target=run,args=('t1',))
        t.setDaemon(True)    #把子线程设置为守护线程,必须在start()之前设置
        t.start()
        t.join()     #设置主线程等待子线程结束
        print('end')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2.6 互斥锁

    def work():
        global n
        lock.acquire()
        temp = n
        time.sleep(0.1)
        n = temp-1
        lock.release()
    
    
    if __name__ == '__main__':
        lock = Lock()
        n = 100
        l = []
        for i in range(100):
            p = Thread(target=work)
            l.append(p)
            p.start()
        for p in l:
            p.join()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    2.7 递归锁

    def func(lock):
        global gl_num
        lock.acquire()
        gl_num += 1
        time.sleep(1)
        print(gl_num)
        lock.release()
    
    
    if __name__ == '__main__':
        gl_num = 0
        lock = threading.RLock()
        for i in range(10):
            t = threading.Thread(target=func,args=(lock,))
            t.start()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2.8 信号量

    def run(n,semaphore):
        semaphore.acquire()   #加锁
        time.sleep(3)
        print('run the thread:%s\n' % n)
        semaphore.release()    #释放
    
    
    if __name__== '__main__':
        num=0
        semaphore = threading.BoundedSemaphore(5)   #最多允许5个线程同时运行
        for i in range(22):
            t = threading.Thread(target=run,args=('t-%s' % i,semaphore))
            t.start()
        while threading.active_count() !=1:
            pass
        else:
            print('----------all threads done-----------')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    3.线程池

    线程池在系统启动时即创建大量空闲的线程,程序只要将一个函数提交给线程池,线程池就会启动一个空闲的线程来执行它。当该函数执行结束后,该线程并不会死亡,而是再次返回到线程池中变成空闲状态,等待执行下一个函数。

    3.1 实现线程池

    #encoding:utf-8
    import time
    import threadpool
    import random
    import threading
    
    def sayhello(str):  #执行方法
        sleep_seconds=random.randint(1, 3)
        print '线程名称:%s,参数:%s,睡眠时间:%s'%(threading.current_thread().name,str,sleep_seconds)
        time.sleep(sleep_seconds)
    
    name_list =['aa','bb','cc','dd']    #总共需要执行4个线程
    start_time = time.time()    #开始时间
    pool = threadpool.ThreadPool(2)     #创建2个线程
    
    requests = threadpool.makeRequests(sayhello, name_list)
    for req in requests:
        pool.putRequest(req)    #将每个请求添加到线程池中
    pool.wait()  #等待线程执行完后再执行主线程
    print '总共运行时间:%d second'% (time.time()-start_time)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
  • 相关阅读:
    Arm架构与神经网络
    Elasticsearch之文档操作(九)
    这一定是你看过的最简单的 pinia 源码
    java中okhttp和httpclient那个效率高
    vue中的ref
    上网行为管控,一款软件就可以实现!
    设计原则思想
    WPF中TextWrapping
    Hadoop Hive HBase调优
    什么情况下mysql 会索引失效?
  • 原文地址:https://blog.csdn.net/weixin_43916074/article/details/126170270