飞道的博客

阿里大牛整理的Python学习笔记:线程,进程,协程,建议收藏

352人阅读  评论(0)

 

一、线程(Thread)

  1、定义:线程是操作系统能进行运算调度的最小单位,它包含在进程中,是进程的实际运作单位,一条线程是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。简单理解:线程是一系列指令的集合,操作系统通过这些指令调用硬件。

  2、同一个线程中的所有线程共享同一个内存空间资源,

 

二、进程(Progress)

  1、定义:一个程序对各资源管理和调用的集合就是进程,比如QQ对网卡、内存、硬盘的调度和管理。对于操作系统来说,某一个进程是统一的整体。进程操作CPU就要先创建一个线程。进程本身是一个资源集合,执行需要靠线程。

 

三、线程和进程的区别

  1、同个进程的线程之间共享内存空间,包括数据交换和通信,但不同进程之间的内存是独立的

  2、子进程是克隆了一份父进程的数据,子进程之间是互相独立的,不能互相访问,数据也不能共享。

  3、两个进程要通信,必须通过一个中间进程代理来实现。

  4、一个线程可以操作同一个进程中的其他线程,但是进程只能操作子进程

  5、对主线程的修改,可能会影响到其他的子线程,因为他们共享内存数据,但对主进程的修改,不会影响其他子进程。

 

四、多线程的代码:


  
  1. import threading
  2. import time
  3. class MyThread(threading.Thread):
  4. """
  5. # 用自定义一个子类的方式来启动线程
  6. """
  7. def __init__(self, n):
  8. super(MyThread, self).__init__()
  9. self.n = n
  10. def run(self):
  11. print( "你好,%s" % self.n)
  12. time.sleep( 2)
  13. start_time = time.time()
  14. thread_list = []
  15. # 启动50个线程
  16. for i in range( 50):
  17. t1 = MyThread( "t%s" % i)
  18. t1.start()
  19. thread_list.append(t1)
  20. # 等待所有线程执行完毕后主线程再继续执行
  21. for i in thread_list:
  22. i.join()
  23. print( "总共执行时间:%s" % float(time.time() - start_time))

 

五、全局解释器锁(GIL)

  1、定义:GIL 是最流行的 CPython 解释器(平常称为 Python)中的一个技术术语,中文译为全局解释器锁,其本质上类似操作系统的 Mutex(即互斥锁,意思是我修改的时候你不能修改,也就是锁的意思)

  2、功能:在 CPython 解释器中执行的每一个 Python 线程,都会先锁住自己,以阻止别的线程执行,这样在同个时间一个CPU只执行一个线程。当然,CPython 不可能容忍一个线程一直独占解释器,check interval 机制会在一个时间段后释放前面一个线程的全局锁执行下一个线程,以达到轮流执行线程的目的。这样一来,用户看到的就是“伪”并行,即 Python 线程在交替执行,来模拟真正并行的线程。

  3、CPython 引进 GIL,可以最大程度上规避类似内存管理这样复杂的竞争风险问题,有了 GIL,并不意味着无需去考虑线程安全,因为即便 GIL 仅允许一个 Python 线程执行,但别忘了 Python 还有 check interval 这样的抢占机制。所以就要引入线程锁的机制,保证同个时间只有一个线程修改数据。

 

 

  4、线程锁的代码如下


  
  1. import threading
  2. import time
  3. num = 0
  4. lock_obj = threading.Lock()
  5. def run():
  6. # 申请锁,使别的线程进不来
  7. lock_obj.acquire()
  8. global num
  9. time.sleep( 1.1)
  10. num = num + 1
  11. # 解锁,解锁后别的线程可以进来
  12. lock_obj.release()
  13. t_list = []
  14. start_time = time.time()
  15. # 启动1000个线程
  16. for i in range( 100):
  17. t1 = threading.Thread(target=run)
  18. t1.start()
  19. t_list.append(t1)
  20. for i in t_list:
  21. i.join()
  22. time.sleep( 3)
  23. print( "num:%d" % num)
  24. print( "time:%f" % float(time.time() - start_time))

 

六、递归锁:

  1、定义:一个锁套另外一个锁,形成锁止循环,这种情况就要用到递归锁RLOCK


  
  1. import threading, time
  2. def run1():
  3. print( "grab the first part data")
  4. lock.acquire()
  5. global num
  6. num += 1
  7. lock.release()
  8. return num
  9. def run2():
  10. print( "grab the second part data")
  11. lock.acquire()
  12. global num2
  13. num2 += 1
  14. lock.release()
  15. return num2
  16. def run3():
  17. lock.acquire()
  18. res = run1()
  19. print( '--------between run1 and run2-----')
  20. res2 = run2()
  21. lock.release()
  22. print(res, res2)
  23. num, num2 = 0, 0
  24. # 这里如果用Lock()就会无限循环,找不到具体用哪个钥匙打开锁,如果用RLock就不会,如果又多重锁嵌套的情况一定要用递归锁
  25. lock = threading.Lock()
  26. for i in range( 1):
  27. t = threading.Thread(target=run3)
  28. t.start()
  29. while threading.active_count() != 1:
  30. print( "当前活跃的线程数:",threading.active_count())
  31. else:
  32. print( '----all threads done---')
  33. print( "打印num和num2:",num, num2)

 

七、信号量(Semaphore)  

  1、允许同时间最多几个线程进入执行,每出来一个进去一个,同时保持预先设置的线程最大允许数量。


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

 

八、事件(Event):

  1、定义:通过标识位和状态,来实现线程之间的交互。简单说,就是一个标志位,只有两种状态,一种是设置(Event.set()),一直是没有设置(Event.clear())。

  2、以下代码实现一个简单事件,一个线程控制红绿灯,另外一个线程控制车子,当红绿灯是红色的时候,车子停止,绿的时候,车子行驶的效果


  
  1. import time
  2. import threading
  3. event = threading.Event()
  4. def lighter():
  5. count = 0
  6. event.set() # 刚开始的标识位先设置绿灯
  7. while True:
  8. if 5 < count < 10: # 改成红灯
  9. event.clear() # 把标志位清了
  10. print( "\033[41;1mred light is on....\033[0m")
  11. elif count > 10:
  12. event.set() # 变绿灯
  13. count = 0
  14. else:
  15. print( "\033[42;1mgreen light is on....\033[0m")
  16. time.sleep( 1)
  17. count += 1
  18. def car(name):
  19. while True:
  20. if event.is_set(): # 代表绿灯
  21. print( "[%s] running..." % name)
  22. time.sleep( 1)
  23. else:
  24. print( "[%s] sees red light , waiting...." % name)
  25. event.wait()
  26. print( "\033[34;1m[%s] green light is on, start going...\033[0m" % name)
  27. light = threading.Thread(target=lighter, )
  28. light.start()
  29. car1 = threading.Thread(target=car, args=( "Tesla",))
  30. car1.start()

  3、Event类还有两个方法,wait()等待被设定,isset()判断是否被设定

后续请敬请期待!

你值得拥有的学习资料来l

1.Python基础语法以及流程控制语句

 

2.Python基础编程

 

3.Python电子书大全(仅展示部分资料)

 

文章到此结束了,希望对大家有帮助,喜欢的记得关注一下小编,点赞收藏奥。还有小编把这些学习资料都已整理完毕,需要的小伙伴私信“学习”即可获得获取方式。感谢大家的阅读 ,记得关注转发收藏奥!


转载:https://blog.csdn.net/weixin_46780321/article/details/106128114
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场