python开发学习笔记(6)————多任务

ps:python开发学习笔记(5)在写的时候发生了丢失。。。。。之后再补吧。今天的多任务学到了生成器,博客分成两部分进行编写。

多任务

多任务:操作系统可以同时运行多个任务。
单核cpu,时间片轮转。并发:假多任务
多核cpu,并行:真多任务

1.线程
1>语法:

使用threading模块

import threading
def main():
	t1 = threading.Thread(target=sing)
	t2 = threading.Thread(target=dance)
	t1.start()
	t2.start()

sing和dance是函数名,这里传递的是引用。主线程在main函数中,子线程分别去执行sing和dance函数。

2>查看线程数量

threading.enumerate() 查看这个函数返回的列表里有几个元素,就有几个线程。可以用len函数。
如果创建Thread时执行的函数运行结束,那么意味着这个子线程结束。
主线程不能提前结束,主线程结束的话,整个程序都会结束。
主线程会等待所有子线程都结束,才会结束。
当调用start()方法后才会创建进程。用Thread()时,不会创建子线程。
多线程时,无法确定谁先执行,谁后执行。

3>线程-注意点

a。如果定义了Thread类的子类,子类中必须定义run方法,因为子类对象调用start()时会自动调用run()方法。
b。多个线程之间是共享全局变量的。函数中全局变量的指向不发生改变时,不需要用global声明。如,list是全局变量,在函数中调用list.append(a)时,不需要声明global,list的值也会发生改变。
c。Thread 参数

t1 = threading.Thread(target=test1, args=(g_nums,))

target指定将来这个线程去哪个函数执行代码,这里指定的是test1()函数
args指定将来调用函数的时候传递什么数据过去。要求调用的函数需要参数传递。args传递的是元组。
d。共享全局变量问题
资源竞争。如果有全局变量,因为多线程是随机运行,在运行过程中,两个子线程的运行可能出现偏差,导致全局变量的更新不能同步,从而导致全局变量的值出错。

4>同步

同步就是协同步调,按预定的先后次序进行运行。

5>互斥锁

当多个线程几乎同时修改某一个共享数据的时候,需要进行同步控制。
互斥锁状态:锁定/非锁定
某个线程要更改共享数据时,先将其锁定,此时资源的状态为“锁定”,其他线程不能更改;直到该线程释放资源,将资源的状态变成“非锁定”,其他的线程才能再次锁定该资源。互斥锁保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性。
threading模块中定义了Lock类。
语法:
a。创建锁

mutex = threading.Lock()

b。锁定

mutex.acquire()

c。释放

mutex.release()
6>死锁、银行家算法

a。死锁
死锁:在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁。
避免死锁:程序设计时尽量避免(银行家算法);添加超时时间等。
b。银行家算法
逐个锁,但是约定好解锁的顺序。

7>udp多线程聊天室

将接收数据和发送数据写为两个函数,分别编入一个子线程

2.进程
1>概念

程序是静态的,进程是一个程序运行起来后,代码+用到的资源称之为进程,它是操作系统分配资源的基本单元。
进程的状态:新建;就绪态:运行的条件都已经就绪,正在等待cpu执行;运行态:cpu正在执行其功能;等待态:等待某些条件满足,例如一个程序sleep了,此时就处于等待态;死亡

2>创建进程
import multiprocessing
def main():
	t1 = multiprocessing.Process(target=test1)
	t2 = multiprocessing.Process(target=test2)
	t1.start()
	t2.start()

与多线程十分相似。
多进程不共享全局变量

3>进程、线程对比

进程,能够完成多任务,如在一台电脑上运行多个QQ
线程,一个进程里的多任务就是多线程。
线程不能够独立执行,必须依存在进程中。
进程理解为工厂的流水线,线程就是流水线上的工人。
优缺点:
线程执行开销小,但不利于资源的管理和保护;而进程正相反。

4>进程间通信Queue队列

两个进程间在内存中的同一块区域读取和存储数据,达到通信的目的。
a。语法

from multiprocessing import Queue
q = Queue(3)  #初始化一个Queue对象,最多可接受三条put消息,不写参数时,存储空间为动态的。
q.put()   #在开辟出来的内存区域存放数据
q.get()   #将内存区域中的数据取出,取得顺序为队列顺序,先进先出
q.full()   返回True,则开辟的内存区域已满,反之,返回False。
q.empty()   返回True,则开辟的内存区域为空,反之,返回False。

b。作用
解耦:降低程序间耦合度,增加灵活度
c。步骤
创建一个队列
创建多个进程,将队列的引用当作实参进行传递,传递到函数中
在一个进程的函数中进行往队列中的写入
在另一个进程的函数中进行从队列中的读取

5>进程池Pool

需要创建的子进程数量不多时,可以利用multiprocessing中的Process动态生成多个进程。但如果需要上百甚至上千个目标时,就要用到Pool方法。
进程池可以重复利用,减少了资源的损耗。
进程池中进程的数量需要测试工程师大量的测试。
语法:

from multiprocessing import Pool
po = Pool(3)   #定义一个进程池,最大进程数为3
for I in range(0,10):
	po.apply_async(worker,(i,))  #Pool().apply_async(要调用的函数,(传递给目标的参数元组,))   每次循环将会用空闲出来的子进程去调用目标   如果要调用的函数没有传入参数,那么后面的参数元组就没有必要写。
	po.close()    #关闭进程池,关闭后po不再接收新的请求
	po.join()    #等待po中所有子进程执行完成,必须放在close语句之后
3.协程
1>迭代器

迭代器是一个可以记住遍历的位置的对象,迭代器对象从集合的第一个元素开始访问,知道所有的元素被访问完结束。迭代器只能往前不能往后。
a。可迭代对象

from collections import Iterable
isinstace(a,Iterable)    a写入一个变量,判断是否为可迭代对象

如果要让一个对象成为一个可迭代对象,可以使用for循环,那么必须实现__iter__方法,且这个方法必须返回一个对象,该对象的类中要有__iter__方法和__next__方法
for循环步骤:
for temp in xxxx:
首先,判断xxxx是否是可以迭代,对象类中是否有__iter__方法
接着,在第一步前提下,调用iter函数,得到xxxx对象的__iter__方法的返回值
最后,__iter__方法的返回值是一个迭代器,自动调用__next__方法
迭代器里有__iter__和__next__两个方法
__next__方法中输出对象的值,并有计数器
b。xrange()
range()生成的列表 的结果(python2.x)
xrange()生成列表的对象
python3中range()已经变为xrange()
类型转换也是应用到了迭代器
tuple(),list()

2>生成器

生成器是一种特殊的迭代器
nums = [x2 for x in range(10)] 列表
创建生成器方法1
nums = (x
2 for x in range(10)) 生成器
创建生成器方法2
例子,斐波那契数列

def create_num(all_num):
	a, b = 0, 1
	current_num = 0
while current_num < all_num:
	yield a
	a, b = b, a+b
	current_num += 1

函数中结果用yield语句,这个就不再是函数,而是一个生成器的模板。
如果调用有yield语句的生成器时,不是调用函数,而是创建一个生成器对象
利用for循环输出生成器对象

3>生成器send方式

用send方式传递的值为yield返回的值

4>yield实现多任务
import time
def task_1():
	while True:
		print(“----1----")
		time.sleep(0.1)
		yield

def task_2():
	while True:
		print(“-----2-----")
		time.sleep(0.1)
		yield

def main():
	t1 = task_1()
	t2 = task_2()
	while True:
		next(t1)
		next(t2)
if __name__ == “__main__”:
	main()

t1和t2交替进行,实现协程

5>协程 greenlet模块
from greenlet import greenlet
import time

def test1():
	while True:
		print(“----A----“)
		gr2.switch()  
		time.sleep(0.5)

def test2():
	while True:
		print(“---B---“)
		gr1.switch()
		time.sleep(0.5)

gr1 = greenlet(test1)
gr2 = greenlet(test2)

gr1.switch()  #切换到gr1中运行
6>协程 gevent

语法:

import gevent
def f(n):
	for i in range(n):
		print(gevent.getcurrent(), i) #getcurrent() 返回当前协程内存地址

g1 = gevent.spawn(f,5)  #创建一个协程对象 greenlet
g2 = gevent.spawn(f,5)
g = gevent.spawn(f,5)
g1,join()  #
g2.join()
g3.join() 

gevent 遇到延时操作就切换

from gevent import monkey
monkey.patch_all()

这句语句可以把代码中的耗时操作换为gevent模块中耗时语句,从而实现协程多任务。

gevent.joinall()  参数为列表

将gevent.spawn()放入joinall参数表中,实现批量管理协程 join操作

7>进程、线程、协程对比

进程是资源分配的单位
线程是操作系统调度的单位
进程切换需要的资源最大,效率很低
线程切换需要的资源一般,效率一般(GIL不考虑的情况下)
协程切换任务资源最小,效率高
多进程、多线程根据cpu核数不一样可能是并行的,但是协程是在一个线程中所以是并发。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
城市应急指挥系统是智慧城市建设的重要组成部分,旨在提高城市对突发事件的预防和处置能力。系统背景源于自然灾害和事故灾难频发,如汶川地震和日本大地震等,这些事件造成了巨大的人员伤亡和财产损失。随着城市化进程的加快,应急信息化建设面临信息资源分散、管理标准不统一等问题,需要通过统筹管理和技术创新来解决。 系统的设计思路是通过先进的技术手段,如物联网、射频识别、卫星定位等,构建一个具有强大信息感知和通信能力的网络和平台。这将促进不同部门和层次之间的信息共享、交流和整合,提高城市资源的利用效率,满足城市对各种信息的获取和使用需求。在“十二五”期间,应急信息化工作将依托这些技术,实现动态监控、风险管理、预警以及统一指挥调度。 应急指挥系统的建设目标是实现快速有效的应对各种突发事件,保障人民生命财产安全,减少社会危害和经济损失。系统将包括预测预警、模拟演练、辅助决策、态势分析等功能,以及应急值守、预案管理、GIS应用等基本应用。此外,还包括支撑平台的建设,如接警中心、视频会议、统一通信等基础设施。 系统的实施将涉及到应急网络建设、应急指挥、视频监控、卫星通信等多个方面。通过高度集成的系统,建立统一的信息接收和处理平台,实现多渠道接入和融合指挥调度。此外,还包括应急指挥中心基础平台建设、固定和移动应急指挥通信系统建设,以及应急队伍建设,确保能够迅速响应并有效处置各类突发事件。 项目的意义在于,它不仅是提升灾害监测预报水平和预警能力的重要科技支撑,也是实现预防和减轻重大灾害和事故损失的关键。通过实施城市应急指挥系统,可以加强社会管理和公共服务,构建和谐社会,为打造平安城市提供坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值