当前位置: 首页 > wzjs >正文

学校门户网站建设报告2021小学生新闻摘抄

学校门户网站建设报告,2021小学生新闻摘抄,网页制作的公司为什么瓯北没有,qq登陆 wordpress1.多任务 1.1多任务的执行方式 并发:指两个或多个事件在同一时间段内发生。指的是任务数多于cpu核数时,通过操作系统的各种任务调用算法,来实现多个任务“一起”(看上去是一起)执行的效果。 并行:指两个…

1.多任务

1.1多任务的执行方式

并发:指两个或多个事件在同一时间段内发生。指的是任务数多于cpu核数时,通过操作系统的各种任务调用算法,来实现多个任务“一起”(看上去是一起)执行的效果。

并行:指两个或多个事件在同一时刻发生(同时发生)。指的是任务数小于cpu核数时真的一起执行。

1.2进程与线程

进程打开一个程序就至少会有一个进程

一个正在运行的程序或者是一个软件就是一个进程,他是操作系统进行资源分配的基本单位。

一个进程默认有一个线程,进程里可以创建多个线程,线程是依附在进程里面的,没有进程就没有线程。

程序启动时默认会有一个主线程(因为线程是程序执行的最小单位)

程序员自己创建的线程可以称为子线程,多线程可以完成多任务

2.线程

2.1单线程

单线程示例:

import time
def speak():print('hello world')time.sleep(2)    #睡眠2sprint('你好,世界')def play():print('劳逸结合')time.sleep(2)print('多做运动')if __name__ == '__main__':speak()play()

__name__  == '__main__'表示如果程序文件直接运行,则执行以下代码 

1.防止别人导入文件的时候执行main里面的方法

2.防止wiondows系统递归创建子进程

2.2多线程创建

使用threading模块里的Thread类创建出示例对象,然后通过start()方法真正的去产生一个新的线程

程序启动会默认有一个主线程

通过start()方法来启动子线程

注意:导入模块时可以导入import threading模块

           创建线程时需要用threading.Thread()

也可以导入from threading import Thread类,创建线程时,直接使用Thread()

2.2.1线程类Thread的参数

group:线程组

target:执行目标的任务名  (也就是函数名)

args:以元组的方式给执行任务进行传参

*args:传任意多个参数

kwargs:以字典方式给执行任务传参

name:线程名

2.2.2步骤

1.导入模块 threading

2.创建子线程 Thread()类

3.守护线程 setDaemon  --设置守护线程,主线程执行完了,子线程也会跟着结束

4.启动子线程 start()

5.阻塞主线程 join()a.join--a是子线程,阻塞主线程,主线程会等待子线程a执行完在执行下面的代码

2.2.3多线程的优势

单线程实现:

import time
t1 = time.time()
def sing(name):print('%s在唱歌' % name)time.sleep(1)    #睡眠2sif __name__ == '__main__':for i in range(4):sing('panda')t2 = time.time()
print('执行时间是',t2-t1)   #执行时间是 4.042494535446167

多线程实现:多个线程同时进行,减少运行时间

import time
import threading    #创建多线程
t1 = time.time()
def sing(name):print('%s在唱歌' % name)time.sleep(1)    #睡眠2sif __name__ == '__main__':for i in range(4):t = threading.Thread(target=sing,args=('panda',))  #一个元素的元组要加,t.start()   #启动线程t2 = time.time()
print('执行时间是',t2-t1)   #0.0010912418365478516

2.2.4多线程的应用

import time
from threading import Threaddef speak():print('hello world')time.sleep(2)    #睡眠2sprint('你好,世界')def play():print('劳逸结合')time.sleep(2)print('多做运动')if __name__ == '__main__':#创建子线程f1 = Thread(target=speak)f2 = Thread(target=play)#设置守护线程f1.setDaemon(True)f2.setDaemon(True)#开启子线程f1.start()f2.start()print("这是主线程")

这里我们可以发现很多想要的数据没有打印出来,因为这些线程同时进行,设置了守护线程,主线程结束,子线程也结束,停留了两秒才输出的就打印不出来,我们就能用join()方法来阻塞主线程

import time
from threading import Threaddef speak():print('hello world')time.sleep(2)    #睡眠2sprint('你好,世界')def play():print('劳逸结合')time.sleep(2)print('多做运动')if __name__ == '__main__':#创建子线程f1 = Thread(target=speak)f2 = Thread(target=play)#设置守护线程f1.setDaemon(True)f2.setDaemon(True)#开启子线程f1.start()f2.start()#阻塞主线程f1.join()    #主线程等f1执行完在执行f2.join()    #f2也进行设置所以f1和f2是同时执行的#修改线程名字f1.setName('线程一')f2.setName('线程二')#获取名字print(f1.getName())print(f2.getName())print("这是主线程")

2.2.5多线程的意义及应用场景

多线程并不是多个线程并发在同一时间点运行,而是cpu有计划的交替执行多个线程

磁盘网络为主的程序 IO密集型,多线程的使用有很大的优势

计算为主的程序 cpu密集型程序,不建议使用多线程操作

2.3线程执行代码的封装

1.继承Thread

2.重构run方法

启动线程start会调用run方法

import time
from threading import Thread
class MyThread(Thread):  #定义一个新子类来继承Thread类def run(self) -> None:  #重构run方法,规定run这个名字表示线程活动的方法print('panda')time.sleep(2)print('play')if __name__ == '__main__':#创建实例线程t = MyThread()t.start()   #panda   play

start和run方法的区别:

start方法是声明分到一个子线程的函数已经就绪,等待被cpu执行

run方法是执行这个线程,自动调用的方法

from threading import Thread
import threadingclass MyThread(Thread):  #定义一个新子类来继承Thread类def run(self) -> None:  #重构run方法,规定run这个名字表示线程活动的方法print(f"当前线程的名字是{threading.current_thread().name}")if __name__ == '__main__':#创建实例线程t1 = MyThread()t2 = MyThread()#启动线程t1.start()  #当前线程的名字是Thread-1t2.start()  #当前线程的名字是Thread-2#run方法启动t1.run()    #当前线程的名字是MainThreadt2.run()    #当前线程的名字是MainThread

2.4线程执行是无序的

他是由cpu调用来决定的,cpu调用哪个线程,哪个线程就先执行,没有调用的线程就不执行

import time
from threading import Thread
import threadingdef task():time.sleep(1)print(f"当前线程的名字是{threading.current_thread().name}\n",end='')if __name__ == '__main__':for i in range(5):t = Thread(target = task)t.start()

线程美化,手动添加换行

2.5线程之间资源共享(全局变量)

import time
from threading import Threadli = []
#写入数据
def wdate():for i in range(5):li.append(i)time.sleep(1)print("写入的数据是:",li)
#读取数据
def rdate():print("读取的数据是:",li)if __name__ == '__main__':#创建子线程t1 = Thread(target=wdate)t2 = Thread(target=rdate)#开启子线程t1.start()t2.start()

输出结果:读取的数据是[0]

                  写入的数据是[0,1,2,3,4]

这里有两种解决办法能读到完整的数据:

1.阻塞线程,加入join等t1任务执行结束,在继续主线程的运行(建议使用)

import time
from threading import Threadli = []
#写入数据
def wdate():for i in range(5):li.append(i)time.sleep(1)print("写入的数据是:",li)
#读取数据
def rdate():print("读取的数据是:",li)if __name__ == '__main__':#创建子线程t1 = Thread(target=wdate)t2 = Thread(target=rdate)#开启子线程t1.start()#阻塞线程t1.join()t2.start()

2.在t1开始后t2开始前,是时间暂停一会,到t1运行完,在执行

import time
from threading import Threadli = []
#写入数据
def wdate():for i in range(5):li.append(i)time.sleep(1)print("写入的数据是:",li)
#读取数据
def rdate():print("读取的数据是:",li)if __name__ == '__main__':#创建子线程t1 = Thread(target=wdate)t2 = Thread(target=rdate)#开启子线程t1.start()#休眠time.sleep(5)t2.start()

2.6资源竞争

a=0
b=1000000#循环一次就给全局变量a+1
def add():for i in range(b):global aa += 1print("第一次",a)
def add2():for i in range(b):global aa += 1print("第二次",a)
add()
add2()

 

from threading import Thread
a=0
b=1000000#循环一次就给全局变量a+1
def add():for i in range(b):global aa += 1print("第一次",a)
def add2():for i in range(b):global aa += 1print("第二次",a)
# add()
# add2()
if __name__ == '__main__':t1 = Thread(target=add)t2 = Thread(target=add2)t1.start()t2.start()

放到一个多线程中就会造成资源竞争(当数量一定大时)

2.7线程同步

两种方式:join和互斥锁

2.7.1.join:等待第一个子线程执行完成之后,代码再继续往下执行,开始执行第二个子线程

from threading import Thread
a = 0
b = 1000000#循环一次就给全局变量a+1
def add():for i in range(b):global aa += 1print("第一次",a)
def add2():for i in range(b):global aa += 1print("第二次",a)
# add()
# add2()
if __name__ == '__main__':t1 = Thread(target=add)t2 = Thread(target=add2)t1.start()t1.join()t2.start()

2.7.2.互斥锁

概念:对共享数据进行锁定,保证多个线程访问共享数据不会出现错误问题:保证同一时刻只能有一个线程去操作

方法:

acquire():上锁

release():释放锁

注意:这两个方法是成对出现的,否则容易形成死锁(死锁:一直等待对方释放锁的情景,死锁会造成应用程序停止响应,不在处理其他任务)

导入模块,也是导入threading模块,导入的是Lock类

from threading import Thread,Lock
a = 0
b = 1000000#创建互斥锁
lock = Lock()
#循环一次就给全局变量a+1
def add():lock.acquire()     #上锁for i in range(b):global aa += 1print("第一次",a)lock.release()     #释放锁
def add2():lock.acquire()  # 上锁for i in range(b):global aa += 1print("第二次",a)lock.release()  # 释放锁
# add()
# add2()
if __name__ == '__main__':t1 = Thread(target=add)t2 = Thread(target=add2)t1.start()#t1.join()t2.start()

注意:互斥锁时多个线程一起去抢,抢到锁的线程先执行

3.进程

3.1.含义:是操作系统进行资源分配和调度的基本单位,是操作系统结构的基础

一个正在运行的程序或者一个软件就是一个进程

程序跑起来就是进程

注意:进程里面可以创建多个线程,多进程可以完成多任务

3.2进程的状态

1.就绪状态:运行条件都已经满足,正在等待cpu执行

2.执行状态:cpu正在执行其功能

3.等待(阻塞)状态:等待某些条件满足,如果一个程序sleep了,此时就处于等待状态

3.3进程的语法结构

multiprocessing模块提供了Process类代表进程对象

3.3.1Process参数

1.target:执行目标任务名,即子进程要执行的任务

2.args:以元组的形式传参

3.kwargs:以字典的形式传参

3.3.2常用的方法

1.start():开启子进程

2.is_alive():判断子进程是否存活,存活返回True,死亡返回False

3.join():等待子进程执行结束

3.3.3常用的属性

name:当前进程的别名。默认Process-N

pid:当前进程的进程编号

在进程中获取进程名只需要 (对象名).name,在线程中需要用getName

1.修改进程名的第一种方法,传参的时候修改

from multiprocessing import Processdef sing():print("唱歌")
def dance():print("跳舞")
if __name__ == '__main__':#创建子进程p1 = Process(target=sing)  #修改进程名的第一种方法p2 = Process(target=dance,name='子进程二')#开启p1.start()p2.start()#访问进程名print(p1.name)   #Process-1print(p2.name)   #子进程二

2.修改进程名的第二种方法,设立对象后,直接进行修改

from multiprocessing import Processdef sing():print("唱歌")
def dance():print("跳舞")
if __name__ == '__main__':#创建子进程p1 = Process(target=sing)p2 = Process(target=dance)#开启p1.start()p2.start()#修改进程名p1.name = '子进程1'p2.name = '子进程2'#访问进程名print(p1.name)   #子进程1print(p2.name)   #子进程2

获取进程编号:导入os模块可以获得主进程的进程编号

os.getpid:获取当前进程的进程编号

os.getppid:获取当前进程的父进程编号

子进程的父进程的pid就是当前py文件主进程的pid

当前py文件主进程的父进程的pid就是pycharme软件中的进程编号

from multiprocessing import Process
import osdef sing():os.getpid()   #获取当前进程的进程编号print(f"sing子进程编号{os.getpid()},父进程编号{os.getppid()}")  #父进程的pid就是py文件主进程的pidprint("唱歌")
def dance():os.getpid()print(f"dance子进程编号{os.getpid()},父进程编号{os.getppid()}")print("跳舞")
if __name__ == '__main__':#创建子进程p1 = Process(target=sing)p2 = Process(target=dance)#开启p1.start()p2.start()#访问进程名print(p1.name)print(p2.name)#查看子进程的进程编号print(f"p1子进程编号{p1.pid}")print(f"p2子进程编号{p2.pid}")print(f"主进程pid{os.getpid()} 父进程pid{os.getppid()}")

 

查看pycharme软件中的进程编号

cmd命令提示符窗口输入tasklist可以查看电脑里面的进程命令

Ctrl+F查找

pycharm64软件的编号就是主进程的父进程的pid

process方法的进一步使用

from multiprocessing import Processdef sing(name):print(f"{name}在唱歌")
def dance(name):print(f"{name}在跳舞")
if __name__ == '__main__':#创建子进程p1 = Process(target=sing,args=('panda',))p2 = Process(target=dance,args=('monkey',))p1.start()p2.start()print('p1的存活状态',p1.is_alive())   #Trueprint('p2的存活状态',p2.is_alive())   #True

存活是因为主进程先执行再执行子进程,所以在主进程中判断是否存活的时候,紫禁城还没有运行完。

使用完毕后需要使子进程死亡,写在主进程中判断存活状态的时候需要加入join阻塞一下

加入join,主进程处于等待状态,子进程处于运行状态

from multiprocessing import Processdef sing(name):print(f"{name}在唱歌")
def dance(name):print(f"{name}在跳舞")
if __name__ == '__main__':#创建子进程p1 = Process(target=sing,args=('panda',))p2 = Process(target=dance,args=('monkey',))p1.start()p1.join()   #这一步执行完的时候相当于p1已经执行完了(在主进程中,所以是死亡)p2.start()p2.join()print('p1的存活状态',p1.is_alive())   #Falseprint('p2的存活状态',p2.is_alive())   #False

3.4进程间不共享全局变量

import time
from multiprocessing import Processli = []
#写入数据
def wdate():for i in range(5):li.append(i)time.sleep(1)print("写入的数据是:",li)
#读取数据
def rdate():print("读取的数据是:",li)if __name__ == '__main__':#创建子进程p1 = Process(target=wdate)p2 = Process(target=rdate)#开启子进程p1.start()p2.start()

加入join方法读取数据输出的结果也始终为空

3.5进程间的通信

Queue(队列)

q.put():放入数据

q.get():取出数据,获取队列中的一条消息,然后将他从队列中移除

q.empty():判断队列是否为空

q.qsize():返回当前队列包含的消息数量

q.full():判断队列是否满了

使用时需要导入模块from queue import Queue

from queue import Queueq = Queue(3)  #最多可以三条消息,没有写或者负值就代表没有上线,直到内存尽头
q.put("我爱世界")
q.put("我爱python")
print(q.qsize())   #2
print(q.full())    #False
q.put("我爱中国")
print(q.full())    #True
print(q.qsize())   #3
print(q.get())
print(q.get())
print(q.empty())   #Flase
print(q.get())
print(q.empty())   #True

可以借助队列完成导入和取出数据的结合

import time
from multiprocessing import Process
from queue import Queueli = ['panda','monkey','bear']
#写入数据
def wdate(q1):for i in range(5):print(f'{i}已经被放入')q1.put(i)time.sleep(0.2)print("写入的数据是:",li)
#读取数据
def rdate(q2):while True:#判断队列是否为空,为空就退出循环if q2.empty():breakelse:print("输出数据",q2.get())print("读取的数据是:",li)if __name__ == '__main__':#创建队列对象q = Queue()#创建子进程p1 = Process(target=wdate,args=(q,))p2 = Process(target=rdate,args=(q,))#开启子进程p1.start()p1.join()p2.start()

4.协程 Coroutine

协程,单线程下的开发,又称微线程,协程时Python中另外一种实现多任务的方式,只不过比线程更小,占用更小的执行单元(理解为需要的资源)。它自带cpu上下文。这样只要在合适的时机,我们可以把一个协程切换到另一个协程。只要这个过程中保存和恢复cpu上下文,那么程序还是可以运行的

注意:线程和进程的操作是由程序触发系统接口,最后的执行者是系统,协程的操作则是程序员

4.1简单实现协程(控制操作时间来控制输出顺序,或者控制代码顺序来控制输出顺序)

import time
def task1():while True:yield 'welcome to python'time.sleep(1)
def task2():while True:yield 'nice to meet you'time.sleep(2)
if __name__ == '__main__':t1 = task1()t2 = task2()while True:print(next(t1))print(next(t2))

4.2应用场景

1.如果一个线程里IO(Input/Outout)操作比较多的时候,可以用协程,常见的IO操作:文件操作,网络请求(爬虫)

2.适合高并发处理

4.3greenlet

使用时也需要导入greenlet模块

from greenlet import greenlet

4.3.1greenlet是一个由C语言实现的协程模块。通过设置switch()来实现任意函数之间的转换

为了更好的使用协程来完成任务,Python中的greenlet模块对其封装,从而使得切换任务变得更简单

安装命令:pip install greenlet

卸载:pip install 模块名

查看已安装模块pip list

如果python解释器安装版本过多或者写在不够彻底可能会产生冲突,这时候就需要在前面加上python -m

4.3.2注意:greenlet属于手动切换,当遇到IO操作,程序会阻塞,而不能进行自动切换

4.3.3通过greenlet实现任务间的切换

from greenlet import greenlet
def sing():print("在唱歌")g2.switch()print("唱完歌了")
def dance():print("在跳舞")print("跳完舞了")
if __name__ == '__main__':#创建协程对象g1 = greenlet(sing)g2 = greenlet(dance)g1.switch()

from greenlet import greenlet
def sing():print("在唱歌")g2.switch()print("唱完歌了")
def dance():print("在跳舞")g1.switch()print("跳完舞了")
if __name__ == '__main__':#创建协程对象g1 = greenlet(sing)g2 = greenlet(dance)g1.switch()g2.switch()

同一条switch语句跳转过的就不再将执行

4.4gevent

使用时也需要先安装,与上一步一样

greenlet实现了协程,但是需要人工切换,gevent是比greenlet更强大而且能够自动切换的第三方库。属于主动切换

使用时需要导入gevent模块

import gevent

4.4.1使用

gevent.spawn(函数名):创建协程对象

gevent.sleep():             耗时操作

gevent.join():                阻塞,等待某个协程执行结束

gevent.joinall():            等待所有协程对象都执行结束在退出,参数是一个协程对象列表

4.4.2grvent自带耗时操作 

import gevent
import time
def sing():print("在唱歌")gevent.sleep(2)print("唱完歌了")
def dance():print("在跳舞")gevent.sleep(3)print("跳完舞了")
if __name__ == '__main__':#创建协程对象g1 = gevent.spawn(sing)g2 = gevent.spawn(dance)#阻塞,等待协程执行结束g1.join()g2.join()

gevent.sleep()模拟了gevent实现的io阻塞,使在唱歌和在跳舞同时执行,如果用time.sleep就会执行完sing函数中的语句,在执行dance函数中的语句(本来加入阻塞应该等待协程执行结束,在跳转,实现了自动跳转)

4.4.3joinall()

import gevent
import time
def sing(name):for i in range(3):gevent.sleep(1)print(f"{name}在唱歌,被送走的第{i}次")
if __name__ == '__main__':gevent.joinall([gevent.spawn(sing,'panda'),gevent.spawn(sing,'monkey')])

gevent.sleep,进行任务切换,实现了并发的效果。

输出结果:

没有gevent,sleep的输出结果:

4.4.4monkey补丁:拥有在运行模块时替换的功能

使用时需要导入模块from gevent import monkey

monkey.patch_all() 是将time.sleep()代码替换成gevent里面自己实现耗时操作的gevent.sleep()代码(需要放在被打补丁者前)

import gevent
import time
from gevent import monkeymonkey.patch_all()
def sing(name):for i in range(3):time.sleep(1)print(f"{name}在唱歌,被送走的第{i}次")
if __name__ == '__main__':gevent.joinall([gevent.spawn(sing,'panda'),gevent.spawn(sing,'monkey')])

5.总结

5.1线程是cpu调度的基本单位,进程是资源分配的基本单位

5.2进程,线程,协程对比

进程:需要切换的资源最大,效率最低

线程:切换需要的资源一般,效率一般

协程:切换需要的资源最小,效率最高

5.3多线程适合IO密集型操作(文件操作,爬虫),多进程适合cpu密集型操作(科学及计算,对视频进行高清解码,计算圆周率)

5.4进程线程、协程都是可以完成多任务的,可以根据自己实际开发需要选择使用。

http://www.dtcms.com/wzjs/45465.html

相关文章:

  • 做amazon当地电信屏蔽了网站seo搜狗
  • 华耀建设网站如何搭建一个网站平台
  • 在哪可以做网站福州模板建站哪家好
  • b2b网站大全台湾佬seo软件代理
  • 投资网站实名认证可以做吗网站怎么做收录
  • 专门做pp他的网站百度指数查询手机版
  • 个人网站可以做论坛么蚂蚁链接bt链接
  • 梨园网站建设各地疫情最新消息
  • 遵义创意网站设计久久seo正规吗
  • 烟台 o2o平台带动做网站行业排名优化价格
  • 阐述网站建设的步骤过程今日头条10大新闻
  • 二维码生成器哪个好用免费优化网站
  • 布吉网站建设哪家便宜怎样上百度做广告
  • 网站备案幕布拍照是什么软件推广是什么工作
  • 网站建设服务那家好太原seo招聘
  • 佛山技术支持 骏域网站建设2023知名品牌营销案例100例
  • 网站推广公司大家好百度竞价查询
  • 花钱做网站不给源码广告推广平台赚取佣金
  • 昌图网站免费广告发布平台
  • 外贸响应式网站建设app拉新佣金排行榜
  • 河南襄县做网站的公司竞价开户推广
  • 不用域名推广网站百度运营公司
  • 某高校门户网站开发案例如何做好网络营销?
  • 科技有限公司你懂的国内专业seo公司
  • 深圳松岗做网站拓客软件排行榜
  • 网站建设方案书例子付费推广平台有哪些
  • 网址大全怎么卸载网站排名seo培训
  • 丹江口网站制作一个新手怎么做推广
  • 没有网站可以做淘宝客武汉大学人民医院官网
  • 武汉网站建设找哪家百度云app下载安装