zoukankan      html  css  js  c++  java
  • Python学习笔记9-多线程和多进程

    一、线程&进程

    对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程,打开一个Word就启动了一个Word进程。进程是很多资源的集合。

    有些进程还不止同时干一件事,比如Word,它可以同时进行打字、拼写检查、打印等事情。在一个进程内部,要同时干多件事,就需要同时运行多个“子任务”,我们把进程内的这些“子任务”称为线程(Thread)。

    由于每个进程至少要干一件事,所以,一个进程至少有一个线程。当然,像Word这种复杂的进程可以有多个线程,多个线程可以同时执行,多线程的执行方式和多进程是一样的,也是由操作系统在多个线程之间快速切换,让每个线程都短暂地交替运行,看起来就像同时执行一样。当然,真正地同时执行多线程需要多核CPU才可能实现。线程是最小的执行单元,而进程由至少一个线程组成。

    我们在做事情的时候,一个人做是比较慢的,如果多个人一起来做的话,就比较快了,程序也是一样的,我们想运行的速度快一点的话,就得使用多进程,或者多线程,在python里面,多线程被很多人诟病,为什么呢,因为Python的解释器使用了GIL的一个叫全局解释器锁,它不能利用多核CPU,只能运行在一个cpu上面,但是你在运行程序的时候,看起来好像还是在一起运行的,是因为操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换到任务2,任务2执行0.01秒,再切换到任务3,执行0.01秒……这样反复执行下去。表面上看,每个任务都是交替执行的,但是,由于CPU的执行速度实在是太快了,我们感觉就像所有任务都在同时执行一样。这个叫做上下文切换。

    二、多线程,python中的多线程使用theading模块

    下面是一个简单多线程

        import threading
        import time
        def sayhi(num): #定义每个线程要运行的函数
         
            print("running on number:%s" %num)
         
            time.sleep(3)
         
        if __name__ == '__main__':
            t1 = threading.Thread(target=sayhi,args=(1,)) #生成一个线程实例
            t2 = threading.Thread(target=sayhi,args=(2,)) #生成另一个线程实例
            t1.start() #启动线程
            t2.start() #启动另一个线程
    

    下面是另一种启动多线程的方式,继承式

        import threading
        import time
        class MyThread(threading.Thread):
            def __init__(self,num):
                threading.Thread.__init__(self)
                self.num = num
         
            def run(self):#定义每个线程要运行的函数
         
                print("running on number:%s" %self.num)
        
                time.sleep(3)
         
        if __name__ == '__main__':
         
            t1 = MyThread(1)
            t2 = MyThread(2)
            t1.start()
            t2.start()
    

    这两种方式没有什么区别,两种写法而已,我个人喜欢用第一种,更简单一些。

    线程等待,多线程在运行的时候,每个线程都是独立运行的,不受其他的线程干扰,如果想在哪个线程运行完之后,再做其他操作的话,就得等待它完成,那怎么等待呢,使用join,等待线程结束

                import threading
                import time
                def run():
                    print('qqq')
                    time.sleep(1)
                    print('done!')
                lis = []
                for i in range(5):
                    t = threading.Thread(target=run)
                    lis.append(t)
                    t.start()
                for t in lis:
                    t.join()
                print('over')
    

    守护线程,什么是守护线程呢,就相当于你是一个国王(非守护线程),然后你有很多仆人(守护线程),这些仆人都是为你服务的,一但你死了,那么你的仆人都给你陪葬。

                import threading
                import time
                def run():
                    print('qqq')
                    time.sleep(1)
                    print('done!')
                for i in range(5):
                    t = threading.Thread(target=run)
                    t.setDaemon(True)
                    t.start()
                print('over')
    

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

            import threading
            from threading import Lock
            num = 0
            lock = Lock()#申请一把锁
            def run():
                global num
                lock.acquire()#加锁
                num+=1
                lock.release()#解锁
            
            lis = []
            for i in range(5):
                t = threading.Thread(target=run)
                t.start()
                lis.append(t)
            for t in lis:
                t.join()
            print('over',num)
    

    下面来个简单的爬虫,看下多线程的效果

            import threading
            import requests,time
            urls  ={
                "baidu":'http://www.baidu.com',
                "blog":'http://www.nnzhp.cn',
                "besttest":'http://www.besttest.cn',
                "taobao":"http://www.taobao.com",
                "jd":"http://www.jd.com",
            }
            def run(name,url):
                res = requests.get(url)
                with open(name+'.html','w',encoding=res.encoding) as fw:
                    fw.write(res.text)
            
            
            start_time = time.time()
            lis = []
            for url in urls:
                t = threading.Thread(target=run,args=(url,urls[url]))
                t.start()
                lis.append(t)
            for t in lis:
                t.join()
            end_time = time.time()
            print('run time is %s'%(end_time-start_time))
            
            #下面是单线程的执行时间
            # start_time = time.time()
            # for url in urls:
            #     run(url,urls[url])
            # end_time = time.time()
            # print('run time is %s'%(end_time-start_time))
    

    三、多进程,上面说了Python里面的多线程,是不能利用多核CPU的,如果想利用多核CPU的话,就得使用多进程,python中多进程使用multiprocessing模块。

        from multiprocessing import Process
        import time
        def f(name):
            time.sleep(2)
            print('hello', name) 
        p = Process(target=f, args=('niu',))
        p.start()
        p.join()
    

     

      

      

      

      

      

      

  • 相关阅读:
    基本技能训练之线程
    关于UEditor的使用配置(图片上传配置)
    PAT 乙级练习题1002. 写出这个数 (20)
    codeforces 682C Alyona and the Tree DFS
    codeforces 681D Gifts by the List dfs+构造
    codeforces 678E Another Sith Tournament 概率dp
    codeforces 680E Bear and Square Grid 巧妙暴力
    codeforces 678D Iterated Linear Function 矩阵快速幂
    codeforces 679A Bear and Prime 100 交互
    XTUOJ 1248 TC or CF 搜索
  • 原文地址:https://www.cnblogs.com/SuKiWX/p/8967396.html
Copyright © 2011-2022 走看看