• 多进程与多线程


    线程和进程:
      进程:对于操作系统来说,打开一个记事本是进程,打开一个word是一个word进行,打开QQ也是一个进程。进程是很多资源的集合。

      线程:打开word后,word可以同时进行打字,拼写检查,打印等事情。在一个进程内部,要同时干很多事,就需要同时运行多个‘子任务’,就把进程内的这些‘子任务’称为线程

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

      python的解释器使用了GIL的一个叫全局解释器锁,它不能利用多核cpu,只能运行在一个CPU上面,但是在运行程序的时候,看起来好像还是在一起运动,是因为操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换到任务2,任务2执行0.01秒,再切换到任务3,执行0.01秒。。。这样反复执行下去。表面上看,每个任务都是交替执行的,但是由于cpu的执行速度太快了,感觉就像所有任务都在同时执行一样,这个称为上下文切换。

     1 '''
     2 多线程:
     3 咱们打开的程序都是一个进程。
     4 线程是包含在进程里的。
     5 进程里面最少有一个线程
     6 线程之间是互相独立的
     7 有一个主线程
     8 '''
     9 '''
    10 cpu是几核的,就只能同时运行几个进程
    11 
    12 python的多线程是利用不了多核cpu的,GIL全局解释器锁的
    13 '''
    14 import threading,time,requests
    15 def sayHi(name):
    16     time.sleep(2)
    17     print(name)
    18 sayHi('lkj')
    19 sayHi('edc')
    20 sayHi('rfv')#串行运行,需要6秒
    21 
    22 
    23 import threading,time,requests
    24 def sayHi(name):
    25     time.sleep(2)
    26     print(name)
    27 t=threading.Thread(target=sayHi,args=('xiahei',))#启动线程
    28 t.start()#开始运行
    29 
    30 
    31 import threading,time,requests
    32 def sayHi(name):
    33     time.sleep(2)
    34     print(name)
    35 for i in range(5):#并行运行,需要两秒
    36     t=threading.Thread(target=sayHi,args=('xiahei',))#启动线程
    37     t.start()#开始运行
     1 import threading,time,requests
     2 def DownHtml(url,name):
     3     comment=requests.get(url).content
     4     f=open(name+'.html','wb')
     5     f.write(comment)
     6     f.close()
     7 urls=[
     8     ['nnzhp','http://www.nnzhp.cn'],
     9     ['dsx','http://www.imdsx.cn'],
    10     ['besttest','http://www.besttest.cn'],
    11 ]
    12 start_time=time.time()
    13 for url in urls:
    14     DownHtml(url[1],url[0])
    15 end_time=time.time()
    16 print(end_time-start_time)#串行运行,时间较长,4.8s
    17 
    18 
    19 import threading,time,requests
    20 def DownHtml(url,name):
    21     comment=requests.get(url).content
    22     f=open(name+'.html','wb')
    23     f.write(comment)
    24     f.close()
    25 urls=[
    26     ['nnzhp','http://www.nnzhp.cn'],
    27     ['dsx','http://www.imdsx.cn'],
    28     ['besttest','http://www.besttest.cn'],
    29 ]
    30 start_time=time.time()
    31 for url in urls:
    32     t=threading.Thread(target=DownHtml,args=(url[1],url[0]))
    33     t.start()
    34 end_time=time.time()
    35 print(end_time-start_time)#时间为0.002秒,时间太短,这个时间不对。因为每个进程至少有一个线程,称为主线程;主线程会自己执行自己的,不会等子线程,所以执行到最后一条语句时,就输出时间,所以该时间是主线程的执行时间。
     1 import threading,time
     2 import requests
     3 def DownHtml(url,name):
     4     comment=requests.get(url).content
     5     f=open(name+'.html','wb')
     6     f.write(comment)
     7     f.close()
     8 urls=[
     9     ['nnzhp','http://www.nnzhp.cn'],
    10     ['dsx','http://www.imdsx.cn'],
    11     ['besttest','http://www.besttest.cn'],
    12 ]
    13 start_time=time.time()
    14 threads=[]#存放刚才启动线程
    15 for url in urls:
    16     t=threading.Thread(target=DownHtml,args=(url[1],url[0]))
    17     t.start()
    18     threads.append(t)
    19 for t in threads:#等待子线程
    20     t.join()#主线程等待子线程
    21 end_time=time.time()
    22 print(end_time-start_time)
     1 多进程
      import multiprocessing,threading 2 import time 3 def run2(): 4 print('这是多线程启动的') 5 def run(): 6 time.sleep(2) 7 for i in range(5): 8 t = threading.Thread(target=run2) 9 t.start() 10 if __name__ == '__main__': 11 for i in range(5): 12 p = multiprocessing.Process(target=run)#Python里面的多线程,是不能利用多核CPU的,如果想利用多核CPU的话,就得使用多进程,python中多进程使用multiprocessing模块。 13 p.start()

     守护进程:

     1 import threading
     2 import time
     3 def sh():
     4     time.sleep(2)
     5     print("测试守护线程")
     6 for i in range(5):
     7     t=threading.Thread(target=sh)
     8     t.start()
     9 print('done')
    10 打印结果:
    11 done
    12 测试守护线程
    13 测试守护线程
    14 测试守护线程
    15 测试守护线程
    16 测试守护线程
    17 
    18 
    19 
    20 import threading
    21 import time
    22 def sh():
    23     time.sleep(2)
    24     print("测试守护线程")
    25 for i in range(5):
    26     t=threading.Thread(target=sh)
    27     t.setDaemon(True)#设置子线程为守护线程,守护线程就是,一旦主线程执行结束,那么子线程立刻结束,不管子线程有没有运行完
    28     t.start()
    29 print('done')
    30 打印结果:
    31 done
    32 
    33 
    34 import threading
    35 import time
    36 def sh():
    37     time.sleep(2)
    38     print('测试线程')
    39 threads=[]
    40 for i in range(5):
    41     t=threading.Thread(target=sh)
    42     t.setDaemon(True)#如果主线程等待子线程的话,那么设置的守护线程就不好使了
    43     t.start()
    44     threads.append(t)
    45 for t in threads:
    46     t.join()
    47 print('done')
    48 打印结果:
    49 测试线程
    50 测试线程
    51 测试线程
    52 测试线程
    53 测试线程
    54 done

    线程锁:

     1 import threading
     2 from threading import Lock
     3 
     4 num = 0
     5 lock = Lock()  # 申请一把锁
     6 
     7 def run():
     8     global num
     9     lock.acquire()  # 加锁
    10     num += 1
    11     lock.release()  # 解锁
    12 
    13 lis = []
    14 for i in range(5):
    15     t = threading.Thread(target=run)
    16     t.start()
    17     lis.append(t)
    18 for t in lis:
    19     t.join()
    20 print('over', num)
    21 
    22 
    23 #加锁是为了多线程的时候同时还修改一个数据的时候,有可能会导致数据不正确
    24 #python3里面锁不加也无所谓,它会自动给你加上锁
  • 相关阅读:
    java数组基础
    java异常处理机制
    java面向对象基础(四):抽象类和接口
    java面向对象基础(二)
    java类路径classpath和包
    java面向对象基础(一)
    Tomcat(二):tomcat配置文件server.xml详解和部署简介
    java集合框架(Collections Framework)
    java基础数据类型包装类
    String、StringBuilder和StringBuffer类
  • 原文地址:https://www.cnblogs.com/wxcx/p/8520115.html
Copyright © 2020-2023  润新知