多进程与多线程

线程和进程:
  进程:对于操作系统来说,打开一个记事本是进程,打开一个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里面锁不加也无所谓,它会自动给你加上锁

 

posted @ 2018-03-07 23:52  飞鸟与新月  阅读(462)  评论(0编辑  收藏  举报