进程:是执行中一段程序,即一旦程序被载入到内存中并准备执行,它就是一个进程
进程是表示资源分配的的基本概念,又是调度运行的基本单位,是系统中的并发
执行的单位。要操作CPU 进行运算,必须要先创建一个线程
线程:单个进程中执行中每个任务就是一个线程。线程是进程中执行运算的最小单位
是一串指令的集合
创建新进程只能克隆父进程,子进程之间是相互独立的,进程只能操作子进程
创建新进程很简单,而进程下的线程空间是共享的,线程可以操作控制统一进程中其他线程
如果主进程运行结束,线程未运行完也会结束,等待线程运行主进程可以用 while 1/input
创建和启用线程的方式:
import thread
1 _thread :_start_new_thread(线程函数,参数/必须是元组形式) 提供了基本的线程和锁定 /不推荐
import threading
2 threading.Thread: 提供了更高级别,功能更全面的线程和锁定
xxx=threading.Thread(target=线程函数,参数/必须是元组形式) 创建线程实例
创建一个子类 继承(threading.Thread):如果要重写父类初始化方法,必须要继承父类方法
4 线程优先级队列Queue : 可以创建一个队列数据结构,
与列表的区别:列表取数据原列表数据还存在,相当于复制,队列数据取走不在存在
1 FIFO(先入先出) queue.Queue(maxsize=0) maxsize指定队列的长度,默认长度为无限长
2 LIFO(后入先出) queue.LifoQueue(maxsize=0)
3 优先级队列 queue. PriorityQueue(maxsize=0) 存储数据时可以设置优先级的队列
生成队列对象:
xxx=queue.Queue() 先入先出
xxx=queue.LifoQueue() 后入先出
xxx=queue. PriorityQueue(优先级级别,数据) 队列中的元素是一个元组类型
Queue 模块中的常用方法:
Queue.qsize() 返回队列的大小 (判断队列大小)
Queue.full() 如果队列满了,返回True,反之False(设定队列大小)
Queue.empty() 如果队列为空,返回True,反之False
Queue.full 与 maxsize 大小对应
Queue.get() 取出数据,获取队列,如果超据会卡住,
(block=flase 参数默认为假,超出会卡住,改成true 超出不会卡住会抛出异常 ,timeout 等待卡住时间)
Queue.get_nowait() 相当于Queue.get() 取值 ,如果超出 会抛出异常 queue.Empty
Queue.put(item) 放入数据,item写入队列的值,
Queue.put_nowait(item) 相当Queue.put(item, False)
Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号
Queue.join() 实际上意味着等到队列为空,再执行别的操作
生产者和消费者模型:
线程模块方法:
threading.currentThread() 返回当前的线程变量。
threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
线程类方法:
run():用以表示线程活动的方法。
start():启动线程活动。
join([time]): 等待至线程中止,直到结束加入的线程,才继续执行下面的线程,可以设置时间
isAlive(): 返回线程是否活动的。
getName(): 返回线程名。
setName(): 设置线程名
time.sleep()睡眠时间
创建多个线程可以用循环实现:
for i in range(10):
t=threading.Thread()
t.start()
多线程并发:本质上是异步的,每个活动的处理顺序是不确定的,随机的
线程锁也叫互斥锁:
加锁方法:
lock 加锁
Rlock 递归锁
如果有嵌套锁,重入锁对象 使单一线程再次获得已持有的锁 用递归锁,否则会锁死
acquire()获取锁对象
release()释放锁
loop()
wait()等待
notify()
notify_all()
xxx=threading.lock() 生成锁的实例
xxx.acquire ()获取锁
xxx.release ()释放锁
Semaphore(信号量) :
互斥锁只允许一把锁,信号量可以同时允许一定数量的线程更改数据,相当于同时 设定几个锁,获取方法和互斥锁一样
xxx=threading.BoundedSemaphore(数量) 生成信号量实例
xxx.acquire ()获取锁
xxx.release ()释放锁
Events事件 :
线程的事件用于主线程控制其他线程的执行,不同线程之间的同步和通信,
程序中的其他线程需要通过判断某个线程的状态来确定自己下一步的操作,。
在初始情况下,Event对象中的信号标志被设置为假。如果有线程等待一个Event对象,
而这个Event对象的标志为假,那么这个线程将会被一直阻塞直至该标志为真。
一个线程如果将一个Event对象的信号标志设置为真,它将唤醒所有等待这个Event对象的线程。
如果一个线程等待一个已经被设置为真的Event对象,那么它将忽略这个事件, 继续执行
xxx=threading.Events()创建一个事件对象,event对象维护一个内部标志(标志的初始为false),通过set()将其设置为true
xxx.set( ) 查询标志位为True 开始一个事件
set:将“Flag”设置为True
xxx.clear()清除set状态
clear:将“Flag”设置为False
xxx.is_set( ) 是否设置set状态
xxx.wait()等待标志位被设定,如果未设置set状态会一直等待,否则过。
事件处理的机制:全局定义了一个“Flag”,如果“Flag”值为 False,那么当程序执行
event.wait 方法时就会阻塞,如果“Flag”值为True,那么event.wait 方法时便不再阻塞。
1 设置信号
使用Event的set()方法可以设置Event对象内部的信号标志为真。Event对象提供了isSet()方法来判断其内部信号标志的状态。
当使用event对象的set()方法后,isSet()方法返回真
2 清除信号
使用Event对象的clear()方法可以清除Event对象内部的信号标志,即将其设为假,当使用Event的clear方法后,isSet()方法返回假
3 等待
Event对象wait的方法只有在内部信号为真的时候才会很快的执行并完成返回。
当Event对象的内部信号标志位假时,则wait方法一直等待到其为真时才返回。
time.sleep()睡眠时间
time.ctime()
time.time()