zoukankan      html  css  js  c++  java
  • pytnon—线程,进程

    一、what线程,what进程

      1、进程

        是资源的整合。一个程序对于操作系统来说就是一个进程、例如打开浏览器、打开word等都是打开一个进程。

      2、线程

      是程序里面的最小执行单元。帮助进程干活的,线程之间相互独立

        多线程多用于处理IO密集型任务频繁写入读出,cpu负责调度,消耗的是磁盘空间

      3、线程是包含在一个进程里面的,一个进程可以有多个线程

      4、一个进程里面默认有一个线程

      5、主线程与子线程,一个程序默认有一个主线程,由主线程来启动子线程

    导入模块

    import threading

    传统方式(单线程)

    串行

    def down_load():
        time.sleep(5)
        print('运行完成')
        
    for i in range(3):
        down_load()

    多线程方式

     并行

    for i in range(3):
        t=threading.Thread(target=down_load)            #实例化一个线程
        t.start()                                       #开始运行
      down_load不要带(),不然属于自己调用了

    线程之间相互独立
    t1=time.time()
    for i in range(3):
        t=threading.Thread(target=down_load)            #实例化一个线程
        t.start()                                       #开始运行
    
    print('运行时间',time.time()-t1)

      上面的代码,总共有4个线程,循环里面启动了3个线程,还有一个主线程在运行所以结果如下

    主线程运行结束打印运行时间,后等待子线程结束

    运行时间 0.0009999275207519531
    运行完成
    运行完成
    运行完成

    查看当前线程数线程

    print(threading.active_count())                 #查看    线程数
    print(threading.current_thread())               #查看  当前线程
    主线程等待子线程结束(并行)
    def down_load():
        time.sleep(5)
        print('运行完成')
    
    
    # 多线程
    t1=time.time()
    for i in range(3):
        t=threading.Thread(target=down_load)
        t.start()
        # t.join()                                      #这里是树形结构不是并行结构
    # t.join()                                          #这里等待的是最后一个线程结束的时间
    
    while threading.activeCount()!=1:                  #主线程等待子线程结束
        pass

    多线程下载图片

    import requests,threading,time
    from hashlib import md5
    def down_load_pic(url):
        req=requests.get(url)
        m=md5(url.encode())
        with open(m.hexdigest()+'.png','wb') as fw:
            fw.write(req.content)
    
    url_list=['http://url.cn/Tfhpen?.jpg',
              'http://www.nnzhp.cn/wp-content/uploads/2019/11/542824dde1dbd29ec61ad5ea867ef245.png'
              'http://www.nnzhp.cn/wp-content/uploads/2019/10/5901238e6ec4a53bfd17e68762c3403a.png',
              'http://www.nnzhp.cn/wp-content/uploads/2019/10/d4b1c8df4d101f531ec2f837ed787e17.png']
    
    t1=time.time()
    for url in url_list:
        t= threading.Thread(target=down_load_pic,args=(url,))
        t.start()
    while threading.activeCount()!=1:
        pass
    #并行下载时间哪个最长,就是哪个时间
    print('运行时间:',time.time()-t1)

     守护线程

    import yagmail,threading
    def send_mail():
        smtp=yagmail.SMTP(host='smtp.126.com',
                     user='newcwl@126.com',
                     password='KVXLMGVQZUZPPZBK'
    
        )
        smtp.send(to='526962645@qq.com',cc=[],subject='测试python邮箱发送内容',
                  contents='正文是:"hahahahahhahahaha"',attachments=[])
    
    # 如果由于网络或者其他原因导致发送缓慢,而主线程没有等待执行完毕
    def async_send_mail():
        t=threading.Thread(target=send_mail)
        t.start()
    # 这里专门启动了一个线程来发邮件
    # 不用等着了

    线程池(根据指定的线程池大小自动分发数据)(数据量大的时候应用)

    import requests,threadpool
    from hashlib import md5
    
    def down_load_pic(url):
        req=requests.get(url)
        m=md5(url.encode())
        with open(m.hexdigest()+'.png','wb') as fw:
            fw.write(req.content)
    
    url_list=['http://www.nnzhp.cn/wp-content/uploads/2019/07/mysql.jpeg',
              'http://url.cn/Tfhpen?.jpg',
              'http://www.nnzhp.cn/wp-content/uploads/2019/03/js.png',
              'http://www.nnzhp.cn/wp-content/uploads/2019/10/d4b1c8df4d101f531ec2f837ed787e17.png']
    
    
    pool=threadpool.ThreadPool(8)                       #实例化线程池(指定大小)
    reqs=threadpool.makeRequests(down_load_pic,url_list)#分配数据(第一个参数是函数,第二个参数是数据)
    [pool.putRequest(req) for req in reqs]
    pool.wait()             #等待
    print('end')

     守护线程(陪葬的)

    只要主线程结束,守护线程立即结束,不管子线程有没有结束

    import threading,time
    def down_load():
        time.sleep(4)
        print('运行结束')
    for i in range(10):
        t=threading.Thread(target=down_load)
        t.setDaemon(True)           #设置子线程为守护线程
        t.start()
    
    print('over')

     获取线程返回值

    import requests,threading,time,threadpool
    from hashlib import md5
    result={}
    def down_load_pic(url):
        req=requests.get(url)
        m=md5(url.encode())
        file_name=m.hexdigest()+'.png'
        with open(file_name,'wb') as fw:
            fw.write(req.content)
        result[file_name]=threading.current_thread()        #获取线程返回值
        return result
    
    url_list=['http://www.nnzhp.cn/wp-content/uploads/2019/07/mysql.jpeg',
              'http://url.cn/Tfhpen?.jpg',
              'http://www.nnzhp.cn/wp-content/uploads/2019/03/js.png',
              'http://www.nnzhp.cn/wp-content/uploads/2019/10/d4b1c8df4d101f531ec2f837ed787e17.png']
    
    t1=time.time()
    for url in url_list:
        t= threading.Thread(target=down_load_pic,args=(url,))
        t.start()
    while threading.activeCount()!=1:
        pass
    #并行下载时间哪个最长,就是哪个时间
    print('运行时间:',time.time()-t1)
    print(result)

     锁

     线程锁,线程锁就是,很多线程一起在操作一个数据的时候,可能会有问题,就要把这个数据加个锁,同一时间只能有一个线程操作这个数据。

    import threading
    num=0
    lock=threading.Lock()
    
    def add():
        global num
        # lock.acquire()      #加锁
        # num+=1
        # lock.release()          #解锁     (如果不解锁,就会产生死锁程序运行到这无法执行)
        
        with lock:          #简写,同注释部分一样
            num+=1
    
    for i in range(20):
        t=threading.Thread(target=add,)
        t.start()
    while threading.activeCount()!=1:
        pass
    print(num)

    多进程

    import multiprocessing,time
    
    def down_load():
        time.sleep(5)
        print('运行完了')
    
    if __name__ == '__main__':#必须加这个才能启动多进程
    
    
        for i in range(5):
            p = multiprocessing.Process(target=down_load)
            p.start()
    
        while len(multiprocessing.active_children())!=0:#等待子进程结束
            pass
        # print(multiprocessing.active_children())    #
        print(multiprocessing.current_process())
        print('end')

    1、如果是CPU密集型代码(循环、计算等),由于计算工作量多和大,计算很快就会达到100,然后触发GIL的释放与在竞争,多个线程来回切换损耗资源,所以在多线程遇到CPU密集型代码时,单线程会比较快;

       算法,计算、数据分析,等不和磁盘打交道的

    2、如果是IO密集型代码(文件处理、网络爬虫),开启多线程实际上是并发(不是并行),IO操作会进行IO等待,线程A等待时,自动切换到线程B,这样就提升了效率。

       磁盘io、网络io、input、output

     
  • 相关阅读:
    [转载]qemu-kvm安装配置
    Hadoop通过c语言API访问hdfs
    hadoop和hdfs环境搭建
    OpenCV installation for Ubuntu 12.04
    homework-01
    linux命令2
    压缩tar
    anaconda 安装opencv
    anconda安装第三方库
    开源代码
  • 原文地址:https://www.cnblogs.com/cwl-bj/p/12683621.html
Copyright © 2011-2022 走看看