线程???进程????区别???何时使用???

  1. 进程:是程序以一个整体的形式暴露给操作系统管理,里边包含了对各种资源的调用,内存的使用,对各种资源的管理的集合,这就叫进程
  2.  
  3. 线程:是操作系统最小的调度单位,是一串指令的集合。
  4.  
  5. 进程要操作CPU,必须要先创建一个线程,所以,只有进程,没有线程,进程是执行不了的。
  6.  
  7. 所有在同一个进程内的线程是共享同一块内存空间,
  8.  
  9. 进程 VS 线程:
    1、线程共享内存空间,进程的内存是独立的
    2、多线程操作数据资源时,数据资源是同一份共享的,多进程是独享一份数资源的,出现子进程也是克隆份数据资源给子进程
    3、同一个进程的线程之间可以直接交流,进程就独立了,进程之间需要交流,必须有通过一个中间代理实现。
    4、创建新的线程很简单,创建新进程需要对其父进程进行一次克隆
    5、一个线程可以控制同一进程里的其他线程, 进程只能操作子进程
    6、对于主线程的修改,有可能会影响到其他线程运行行为,对于父进程的修改,不会影响子进程
  10.  
  11. 何时用多线程:
    IO操作不占用CPU,计算占用CPU
    python多线程不适合CPU密集操作型的任务,适合IO密集型的任务。
  1. import threading
  2. import time,random
  3.  
  4. m=random.Random()
  5.  
  6. def task(name,sleep_time):
  7. print("任务:%s"%name,threading.current_thread(),threading.active_count())
  8. time.sleep(sleep_time)
  9. print("任务 %s 运行结束"%name,threading.active_count())
  10.  
  11. thread_list=[]
  12.  
  13. start_time=time.time()
  14. for i in range(50):
  15. t=threading.Thread(target=task,args=("task"+str(i),m.randint(1,4)))
  16. t.setDaemon(True) #这就是把当前线程设定为守护线程,必须在start()之前。
  17. # 守护线程:是守护主线程的仆人,主线程的执行不再等待子线程的结束,但是主线程一旦结束退出,所有守护线程会被强制退出
  18. t.start()
  19. thread_list.append(t)
  20.  
  21. print("当前活跃的线程数:%s"%threading.active_count())
  22.  
  23. #等待线程结束不要等待守护线程,因为没有意义
  24. # for t in thread_list:
  25. # t.join() #这是主线程等待一个线程完成以后
  26.  
  27. print("all time:%s"%(time.time()-start_time),threading.current_thread(),threading.active_count())

线程锁 + 信号量

  1. import threading,time,random
  2. m=0
  3. lock=threading.Lock() #线程排它锁
  4. def upup():
  5. global m,lock
  6. lock.acquire() #加锁,如果不加锁,在py2.x时,由于执行获取gil锁仅与CPU指令和CPU时间片段有关,这样加锁,同一时间仅有一个线程可以执行该函数
  7. # 可能导致线程在修改数据时拿到的不是其他线程修改完的数据,而是CPU寄存器中的数据,
  8. # 再去进行修改,然后重新赋值,这样最终结果就不正确了。而且不可控制。
  9. # py3.x没有这个问题,但是官方没有声明,所以还是需要加锁的。
  10. m+=1
  11. lock.release()
  12. print("num is %s"%m)
  13. time.sleep(1) #释放锁
  14.  
  15. #锁住数据以后,其他线程在获取锁资源之前,是无法修改该数据的,这么一来,被加锁的代码段将会是串行的,
  16. # 所以,原则上,被加锁的代码段尽量要短并且效率高
  17.  
  18. for i in range(50):
  19. # m=upup(m)
  20. t=threading.Thread(target=upup)
  21. t.start()
  22.  
  23. # for i in range(50):
  24. # m=upup(m)
  25. print("m 最后是:%s"%m)
  26.  
  27. # 递归锁:还有一种情况,就是函数之间存在调用,每个函数又都需要线程排它锁,因为锁的定义就是一个全局的,
  28. # 此时程序运行时,当开始了函数中调用的函数的锁以后,该线程获取到两把锁对应两个函数,
  29. # 这时,被函数调用的函数执行完成以后,是无法释放线程排它锁的,原因就是进行操作的线程不知道手里的钥匙是哪个锁的,就出不来了,其实是被排他了。
  30. # 这样的情况下,诞生了递归锁,
  31. # 定义写法是:
  32. lock=threading.RLock()
  33. # 使用方法与普通的线程排它锁完全一致。
  34.  
  35. #信号量:当一个函数的执行是允许有限数量个线程同时去执行的时候适用。
  36. semaphore=threading.BoundedSemaphore(5) #定义一个允许最多5个线程同时执行的信号量。
  37.  
  38. def my_name(sleep_time):
  39. semaphore.acquire()
  40. time.sleep(sleep_time)
  41. print(threading.current_thread())
  42. semaphore.release()
  43.  
  44. st=random.Random()
  45.  
  46. tl=[]
  47. for ii in range(500):
  48. ttt = threading.Thread(target=my_name,args=(st.randint(1,3),))
  49. ttt.start()
  50. tl.append(ttt)
  51. print("当前存活线程数:",threading.active_count())
  52.  
  53. for rt in tl:
  54. rt.join()
  55.  
  56. print("主线程最终结束了")

线程队列,生产者、消费者模型

  1. import queue #导入队列模块
  2. import time,threading,random
  3.  
  4. qq=queue.Queue() #创建队列,除了这种普通队列Queue以外,还有LifoQueue,还有PriorityQueue,有个初始化可选参数,maxsize=0,默认是0不限制,传入数字,就是队列中最多有多少个对象
  5. # 特性不同:队列都是只能取出一次,取出来就没有了。
  6. # 1、Queue:先进先出,
  7. # 2、LifoQueue:先进后出,
  8. # 3、PriorityQueue:优先级队列,这个队列的使用主要是优先级,数字是越小的数字越优先出,字母是按照ascii码,建议直接向队列中填充的是元组,第一个元素就是优先级数字
  9.  
  10. def producer(name,p_time): #生产者方法
  11. count=0
  12. print("我是厂家【%s】,我【%s】秒生产一个包子"%(name,p_time))
  13. while True:
  14. qq.put("【%s】生产的 包子【%s】"%(name,count)) #向队列里塞入一个对象,我这里塞入的是一个字符串
  15. print("生产厂家【%s】生产了包子【%s】"%(name,count))
  16. count +=1
  17. # time.sleep(p_time)
  18. if count>99:
  19. break
  20. print("仓库有【%s】个包子"%qq.qsize())
  21. qq.join()
  22. print("仓库没货了")
  23.  
  24. def consumer(name,c_time): #消费者方法
  25. print("我是吃货【%s】,我【%s】秒吃完一个包子"%(name,c_time))
  26. while True:
  27. print("【%s】吃了%s"%(name,qq.get())) #从队列里取出一个对象,因为我知道塞入的是字符串,这里取出来直接打印了
  28. time.sleep(c_time)
  29. qq.task_done()
  30.  
  31. rd=random.Random()
  32. for i in range(2): #启动两个生产者的线程,调用生产者方法
  33. pt=threading.Thread(target=producer,args=("pt%s"%i,rd.randint(1,3)))
  34. pt.start()
  35.  
  36. for i in range(10): #启动10个消费者线程,调用消费者方法
  37. ct=threading.Thread(target=consumer,args=("ct%s"%i,rd.randint(2,4)))
  38. ct.start()
  39.  
  40. # qq.get() #从队列中取出一个对象,取不出来就阻塞,直到取出来,可以传参block=False就不阻塞了,
  41. # 但是取不到就报异常,参数timeout=None是阻塞超时时间,超时后还取不出来,就报异常
  42. # qq.put() #向队列中塞入一个对象,塞不进去就阻塞,直到能塞进去,可以传入参数block=False就不阻塞了,
  43. # 但是塞不进去就报异常,参数timeout=None是阻塞超时时间,超时后还塞不进去,就报异常
  44. # qq.qsize() #返回当前队列中的对象数量
  45. # qq.get_nowait() #不阻塞的取得一个对象,取不出来就异常
  46. # qq.put_nowait() #不阻塞的塞入一个对象,塞不进去就异常
  47. # qq.full() #检查队列是否达到队列设定的最大存放对象的数量,达到返回True,否则返回False
  48. # qq.empty() #检查队列是否为空了,为空返回True,否则返回False
  49. # qq.task_done() #这个方法是最后队列中的对象被消费后,告诉join()。。。。写程序时task_done()与join()两个方法必须配套出现,不然就会阻塞,
  50. # qq.join() #这里如果队列中有对象,则阻塞,没有就不再阻塞

事件驱动!!!(面向事件):

  1. #写个红绿灯吧,事件触发,红灯亮了,车停了,绿灯亮了,车子开走了
  2. import threading,time
  3.  
  4. # event=threading.Event() #定义一个Event对象,触发器
  5. #
  6. # event.wait() #如果设定了标志位,就不阻塞,否则就阻塞
  7. # event.set() #设定标志位
  8. # event.clear() #清除标志位
  9.  
  10. #这个阻塞等待,可以影响任何线程
  11.  
  12. #红绿灯例子
  13.  
  14. event=threading.Event() #定义一个触发器,来控制红灯,绿灯
  15. def light(): #红绿灯闪烁的方法
  16. count=0 #记录秒数
  17. while True:
  18. if count<=5:#红灯
  19. print("\033[41;1mred light is on!!!!!\033[0m") #红灯亮了
  20. event.clear() # 红灯,车辆线程要停止运行,所以,触发器将标志位清除
  21.  
  22. elif count > 5 and count<10: #绿灯
  23. print("\033[42;1mgreen light is on.....\033[0m") #绿灯亮了
  24. event.set() #绿灯,车辆线程要继续运行,往前通过,所以触发器车顶标记位
  25. else:
  26. count=0
  27. time.sleep(1)
  28. count +=1
  29.  
  30. def car_run(name): #车辆通行的方法
  31. while True:
  32. if event.is_set(): #为了打印出是红等还是绿灯,所以需要判定标记为是否设定,根据红绿灯的逻辑,设定为绿灯,没设定是红灯
  33. print("【%s】看到了绿灯,往前冲!!!"%name)
  34. else:
  35. print("【%s】红灯了!!!,停车!!!" % name)
  36. event.wait() #利用触发器的wait()来根据标记位进行阻塞运行。
  37. time.sleep(0.3) #这个是为了车车们不要跑太快,多不安全呀,呵呵
  38. lttt=threading.Thread(target=light)
  39. lttt.start()
  40. for i in range(10): #弄出来10个车车线程
  41. car=threading.Thread(target=car_run,args=("car_%s"%int(i),))
  42. car.start()

借楼补充:

断言:断定一个事务 是某些类型,用途是,后续的程序无法回滚,绝对不能出错,可以加断言,因为断言不对,就直接报错了。

  1. #断言
  2. import importlib
  3. aa=importlib.import_module("mode3_3.反射")
  4. md=aa.Dog("侯杰")
  5.  
  6. assert type(md.name) is str #断言,断定一个事务 是某些类型,
  7. md.eat()#断言用途是,后续的程序无法回滚,绝对不能出错,可以加断言,因为断言不对,就直接报错了。

动态引入模块:

  1. #首先是知道模块路径的,这样可以给各种模块附加模块了
  2. #因为这里可以使用字符串,就能用变量,就能随便换了
  3.  
  4. mm=__import__("mode3_3.反射") #导入的是模块名 导进来的就是模块lib,mm就是导入的模块路径,与写的字符串不一致,上一级路径(也是字符串中明确写的)。
  5. #这是解释器自己用的,官方建议不要用这个
  6. #官方建议用importlib
  7.  
  8. md=mm.反射.Dog("袁伟") #模块路径下的模块下的类
  9. md.eat()
  10.  
  11. import importlib
  12.  
  13. mm=importlib.import_module("mode3_3.反射") #这样是动态的引入了模块名。mm就是模块了,与上边的方法不同点在于最终结果,上边的是路径,这里的是与字符串一致的模块
  14. md = mm.Dog("郭辉")
  15. md.eat()

python3.x Day6 多线程的更多相关文章

  1. Python3.5+PyQt5多线程+itchat实现微信防撤回桌面版代码

    weChatThread线程类 之前一直不会python多线程,写这个程序的时候,发现不用多线程会陷入无限未响应状态.于是学了半天python多线程,但是在主函数里写的时候,发现一个问题,Ui主线程和 ...

  2. python3.x Day6 socketserver

    socketserver是啥? 简化了编写网络服务器,就是对于socket的再一次封装sockerserver包含4个类可以使用:A=socketserver.TCPServer() #用于TCP/I ...

  3. Python3 多进程和多线程

    Unix/Linux操作系统提供了一个fork()系统调用,它非常特殊.普通的函数调用,调用一次,返回一次,但是fork()调用一次,返回两次,因为操作系统自动把当前进程(称为父进程)复制了一份(称为 ...

  4. python3.x Day6 IO多路复用

    IO多路复用import asyncio 这个是异步IO模块 这个还不知道怎么用 select poll epoll 都是IO多路复用 windows 仅支持select linux2.6以后 支持e ...

  5. python3.x Day6 多进程

    多进程:1.每个子进程申请到的资源都是独立的,不与其他进程共享.2.语法上和线程基本上差不多,使用multiprocessing.Process(target=xxxx,args=(xxx,xxx,x ...

  6. python3.x Day6 paramiko

    python3 paramiko模块,用来进行远程操作linux服务器,利用的就是ssh #利用用户名,密码,进行连接 import paramiko #创建一个SSH对象 ssh=paramiko. ...

  7. python3 基本使用多线程

    #coding=utf-8 import threading #进口threading from time import sleep import time def task1(): print (& ...

  8. python3迷宫,多线程版

    上图: 直接上代码 #!/usr/bin/python3 #coding=GB2312 import tkinter as tk import threading import time import ...

  9. python3.x Day6 协程

    协程:#定义来自牛人alex博客协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程.协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈 ...

随机推荐

  1. ROS学习笔记八:基于Qt搭建ROS开发环境

    1 前言 本文介绍一种Qt下进行ROS开发的完美方案,使用的是ros-industrial的Levi-Armstrong在2015年12月开发的一个Qt插件ros_qtc_plugin,这个插件使得Q ...

  2. 51nod 1068 Bash游戏 V3

    列出前几项可以发现是个规律题,不要被题目的文字所欺骗,字符串处理10^1000即可 #include <bits/stdc++.h> using namespace std; int ge ...

  3. 洛谷 P3285 [SCOI2014]方伯伯的OJ

    看到这题,第一眼:平衡树水题,随便做一做好了 然后....我在花了n个小时去调试(维护平衡树父节点)之后,... 调了三个小时后,第一次失败的代码(只能查找排名为k的用户编号,不能根据编号查排名) # ...

  4. css超出部分显示省略号

    单行文本 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...

  5. Join方法,yield方法,线程的优先级

  6. NBA15-16赛季半程有感

    2015-2016 新赛季NBA已经开打半程又多了,这半个赛季我们见证了 勇士的三节打卡:骑士的磨合反复:马刺的老骥伏枥: 当然还有窝火的XJBD. 豪哥200W刀签约黄蜂,打出来800W刀的身价,无 ...

  7. Caused by: javax.el.PropertyNotFoundException: Property 'product' not found on type java.lang.String

    今天在JSP利用EL表达式取值报了 "javax.el.PropertyNotFoundException”,经过debug和打印将问题定位到这段代码: HTML应该是没啥问题,看提示在ja ...

  8. spark 学习路线及参考课程

    一.Scala编程详解: 第1讲-Spark的前世今生 第2讲-课程介绍.特色与价值 第3讲-Scala编程详解:基础语法 第4讲-Scala编程详解:条件控制与循环 第5讲-Scala编程详解:函数 ...

  9. 5 Transforms 转移 笔记

    5 Transforms 转移 笔记   Transforms    Unfortunately, no one can be told what the Matrix is. You have to ...

  10. OpenGL VAO, VBO 使用简介

    参照代码样例: // This function takes in a vertex, color, index and type array // And does the initializati ...