网络传输进阶篇----并发

一、并发是什么

? 较为通俗的去理解并发这件事情本身,这就要牵扯到计算机的发展。我再这笼统的概括,在网上能够找到十分详细的计算机发展史。

? https://blog.csdn.net/zzwu/article/details/77792789——请参见大佬的文章

? 在计算及一开始,工业生产能力并不能实现如今的多核的生产条件,当然也包括 那个时候并没有相关的理论。所以,在那个时候运行计算机那是相当的麻烦,很多人只能排着队等着来。这时候,优秀的程序猿就思考着为什么不能在计算机计算他人的内容的时候,接着运行别人的呢。因此他们就想到了并发——同时运行多个程序在一个处理器上。因为当程序在运行的时候,除开一些较为复杂的计算下,处理器占用较为多之外,很多时候都是进行的文件的读写 也就是 I/O 功能,这只占用计算机处理器的一小部分,大多数的部分就只能白白浪费。毕竟,效率就是生产力啊!!

? 引用百度的正规称呼——“并发,在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。”——应用自百度

二、进程——基本内容

1.什么是进程

? 正在进行的一个过程或者说一个任务。

2.进程和程序

? 程序是一对代码,进程则是程序的运行过程。

3.并发和并行

? 并发是看起来是同时进行了,但实际是处理器在多个任务之间的高速来回移动。

? 并行是真正的同时运行,但条件是得有多个CPU。因为一个CPU只能执行一个任务。

?

三、进程——multiprocessing模块

1.Process类

? **创建进程**

?

Process([group [, target [, name [, args [, kwargs]]]]]),由该类实例化得到的对象,可用来开启一个子进程?强调:1. 需要使用关键字的方式来指定参数2. args指定的为传给target函数的位置参数,是一个元组形式,必须有逗号

? **参数介绍**

group参数未使用,值始终为None?target表示调用对象,即子进程要执行的任务?args表示调用对象的位置参数元组,args=(1,2,‘egon‘,)?kwargs表示调用对象的字典,kwargs={‘name‘:‘egon‘,‘age‘:18}?name为子进程的名称

? **方法介绍**

p.start():启动进程,并调用该子进程中的p.run() p.run():进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法  ?p.terminate():强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别小心这种情况。如果p还保存了一个锁那么也将不会被释放,进而导致死锁p.is_alive():如果p仍然运行,返回True?p.join([timeout]):主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。timeout是可选的超时时间。

? **属性介绍**

p.daemon:默认值为False,如果设为True,代表p为后台运行的守护进程,当p的父进程终止时,p也随之终止,并且设定为True后,p不能创建自己的新进程,必须在p.start()之前设置?p.name:进程的名称?p.pid:进程的pid

2.Process类的使用

? **windows的Process必须在 if name == ‘main‘:下**

?

? **创建方式一**

#!/usr/bin/python# -*- coding:utf-8 -*-from multiprocessing import Process??def people(name, sex):    print("%s is %s" % (name, sex))??if __name__ == ‘__main__‘:    p1 = Process(target=people, args=("张三", "man",))    p2 = Process(target=people, args=("李四", "man",))    p3 = Process(target=people, args=("狗蛋", "female",))?    p1.start()    p2.start()    p3.start()?    print("主要程序")

? **方式二**

#!/usr/bin/python# -*- coding:utf-8 -*-from multiprocessing import Process??class People(Process):    def __init__(self, name, sex):        super().__init__()        self.name = name        self.sex = sex?    def run(self):        print("%s is %s" % (self.name, self.sex))??if __name__ == ‘__main__‘:    p1 = People("张三", "man")    p2 = People("李四", "man")    p3 = People("狗蛋", "female")?    p1.start()    p2.start()    p3.start()?    print("主要程序")

3.joint

? 通过上面的创建,能发现的一个问题就是:在主进程都已经结束完成后,子进程并没有完成。因为我们看到的代码只是向处理器发出了一个信号,但是实际上并没有运行。而主进程并不需要进行进程方面的创建,直接就运行了。

? 那么,主进程能够等着子进程运行完成之后,自己再进行吗?

? 答案显然是可以的。

? 只需要在主进程之前加上joint()就可以。

? joint就是认为的对主程序进行阻塞,只有joint所对应的子进程运行完成后,主进程才能运行。

#!/usr/bin/python# -*- coding:utf-8 -*-from multiprocessing import Process??def people(name, sex):    print("%s is %s" % (name, sex))??if __name__ == ‘__main__‘:    p1 = Process(target=people, args=("张三", "man",))    p2 = Process(target=people, args=("李四", "man",))    p3 = Process(target=people, args=("狗蛋", "female",))?    p1.start()    p2.start()    p3.start()?    p1.join()    p2.join()    p3.join()?    print("主要程序")        #注意:有多少个对象,就要有对应的join

? **注意:加上joint的进程并不是串行**

? 因为joint阻塞了主进程,但是子进程还是并发的在进行着。和串行一个一个运行还是有着本质的不用的。

? **对象其他属性或方法**

? **terminal 与 is——alive**

#!/usr/bin/python# -*- coding:utf-8 -*-from multiprocessing import Process??def people(name, sex):    print("%s is %s" % (name, sex))??if __name__ == ‘__main__‘:    p1 = Process(target=people, args=("张三", "man",))    p1.start()             p1.terminate()    print(p1.is_alive())        print("主要程序")

运行后的结果:

True主要程序

? **name 与 pid**

?

#!/usr/bin/python# -*- coding:utf-8 -*-from multiprocessing import Process??def people(name, sex):    print("%s is %s" % (name, sex))??if __name__ == ‘__main__‘:    p1 = Process(target=people, args=("张三", "man",))    p1.start()?    print(p1.name, p1.pid)?    print("主要程序")

运行结果:

Process-1 17072主要程序张三 is man

4.守护进程

? 守护进程就是伴随主进程左右的子进程,在主进程结束之前,自己绝对不会结束的子进程。

? **强调:一、主进程结束就终止;二、守护进程内不能开子进程,否则抛出异常**

?

#!/usr/bin/python# -*- coding:utf-8 -*-from multiprocessing import Process??def people(name, sex):    print("%s is %s" % (name, sex))??if __name__ == ‘__main__‘:    p1 = Process(target=people, args=("张三", "man",))?    p1.daemon = True    p1.start()?    print("主进程")?# daemon必须要在start上面

5.互斥锁

? 并发虽然解决了效率的问题,但是也带来了一个问题就是容易带来错乱。

from multiprocessing import Processimport os,timedef work():    print(‘%s is running‘ %os.getpid())    time.sleep(2)    print(‘%s is done‘ %os.getpid())?if __name__ == ‘__main__‘:    for i in range(3):        p=Process(target=work)        p.start()

运行结果:

第一次结果19428 is running19364 is running18716 is running19428 is done18716 is done19364 is done??第二次结果28012 is running7920 is running23080 is running7920 is done28012 is done23080 is done

? 互斥锁将解决这个问题。

? 互斥锁就是一个门卫,谁抢到谁先进去,剩下的人在下面等着。

? 虽然保证了质量,但是效率也就不存在了。互斥锁将本来的并发变成了串行。

from multiprocessing import Process,Lockimport os,timedef work(lock):    lock.acquire() #加锁    print(‘%s is running‘ %os.getpid())    time.sleep(2)    print(‘%s is done‘ %os.getpid())    lock.release() #释放锁if __name__ == ‘__main__‘:    lock=Lock()    for i in range(3):        p=Process(target=work,args=(lock,))        p.start()     #加上锁acquire之后一定要在最后release 否则下面的数据根本进不去

? **互斥锁与joint**

? joint是一个一个的运行,即上一个结束,下一个进去

? 互斥锁是多个一起去抢,谁抢到谁运行。然后再抢,在运行。如此循环往复。

? 即,join是将一个任务整体串行,而互斥锁的好处则是可以将一个任务中的某一段代码串行,比如只让task函数中的get任务串行

def task(name,):    search(name) # 并发执行?    lock.acquire()    get(name) #串行执行    lock.release()

? 互斥锁中可以有部分是并发执行,而joint无法做到

6.队列

? **重要**

#队列的创建Queue([maxsize]):创建共享的进程队列,Queue是多进程安全的队列,可以使用Queue实现多进程之间的数据传递。    #!/usr/bin/python# -*- coding:utf-8 -*-from multiprocessing import Processimport queue??def people(name, sex):    print("%s is %s" % (name, sex))??if __name__ == ‘__main__‘:    p1 = Process(target=people, args=("张三", "man",))    p2 = Process(target=people, args=("李四", "man",))    p3 = Process(target=people, args=("狗蛋", "female",))?    q = queue.Queue(2)    q.put(p1)    q.put(p2)    print(q.full())?    p1.start()    p2.start()    p3.start()        print(q.get())    print(q.get())?    print(q.empty())?    print("主要程序")    #如果q.put()和 q.get()查过2 程序会卡住不再运行

本文知识点引自与http://www.cnblogs.com/linhaifeng/大佬

原文地址:https://www.cnblogs.com/takafter/p/9385924.html

时间: 2024-08-08 12:39:45

网络传输进阶篇----并发的相关文章

网络编程进阶:并发编程之协程、IO模型

协程: 基于单线程实现并发,即只用一个主线程(此时可利用的CPU只有一个)情况下实现并发: 并发的本质:切换+保存状态 CPU正在运行一个任务,会在两种情况下切走去执行其他任务(切换有操作系统强制控制),一种情况是该任务发生了阻塞,另一种是该任务计算的时间过长或有一个优先级更高的程序替代了它 在介绍进程理论时,提及进程的三种执行状态,而线程才是执行单位,所以也可以将上图理解为线程的三种状态 如果多个任务都是纯计算的,上图的情况2并不能提升效率,因为只是让CPU来回切,这样看起来所有任务都被"同时

网络编程进阶及并发编程

并发编程之多进程 进程理论 进程 进程:正在运行的一个过程或一个任务.负责执行任务的是cpu. 程序与进程的区别:程序只是一堆代码,而进程指的是程序的运行过程. 注意同一个程序执行两次,是两个进程.比如打开两个QQ,登陆的是不同人的QQ号. 并行与并发 无论是并行还是并发,在用户看来都是'同时'运行的,不管是进程还是线程,都只是一个任务而已,真是干活的是cpu, cpu来做这些任务,而一个cpu同一时刻只能执行一个任务. 并发:并发是看起来像是一起执行,实际上是通过在不同人物之间快速切换,使任务

【VMCloud云平台】SCVMM进阶篇(一)网络虚拟化(2)

上一篇,我们讲了下最基本的SDN,就是使用CA地址的客户端如何去访问外部的网络?网络虚拟化里是否有类似"VLAN虚拟网关"的概念?还有PA跟CA到底之间具体的联系是如何实现的? 本篇涉及的网络架构由于是SCVMM进阶篇,就把SCVMM部分单独拿出来扩展,随着SCVMM进阶篇的推进,将会不断更新SCVMM架构图,图中Red.Blue两朵云分别代表租户的两个网络,Host-GW是用来做VMM网关(IP地址设置为23): 1. 上一篇中,我们创建了SC_NetWork作为主机间通信的&quo

通过“分布式系统的8大谬误”反思APP的设计 第七篇 谬误7:网络传输无需任何开销

谬误 7:网络传输没有什么代价 Arnon Rotem-Gal-Oz's 在解释这条谬误的时候具体指出了,需要从一下两方面来看: 第一,你需要考虑应用和网络接口之间的数据传输开销.除了带宽和时延会带来开销,数据的序列化和反序列化也会影响到性能.苹果在2010 WWDC session 117"基于服务器的用户体验"的演讲中,对比了xml,json,plist这几种数据传输格式的大小以及加载时间.对比结果表明,各种数据格式的大小都差不多,但是解析的时间相差很大:解析xml需要812毫秒,

【VMCloud云平台】SCVMM进阶篇(一)网络虚拟化(1)

SCVMM基础篇已经告一段落了,今天咱们开始SCVMM进阶篇中的第一篇网络虚拟化,其实这个是博主最不想提的一个点,因为实在很难理解,如果对虚拟化没有一个大概的概念的话,完全不清楚网络虚拟化在虚拟化中以及云计算中的一个地位是怎么样的. 放眼当下,虚拟化技术已经不仅仅局限于服务器,基于服务器下的各种概念都可以被"虚拟化",软件定义网络(SDN)就是一个,而网络虚拟化就是SDN中的一种体现. 将现有网络通过微软提供的虚拟化技术加上NVGRE标签封装,使得不同租户之间使用相同IP也不会造成冲突

《C#网络编程高级篇之网页游戏辅助程序设计(扫描版)》

<C#网络编程高级篇之网页游戏辅助程序设计>通过编写C#网络编程语言中具有代表性的实例,向读者深入细致地讲解了如何利用C#语言进行网页游戏辅助程序设计.本书通过大量的代码引导读者一步步学习和掌握C#的网络应用编程的方法和网页游戏辅助程序的设计技术. <C#网络编程高级篇之网页游戏辅助程序设计>涉及的领域包括多线程编程技术.socket套接字编程.tcp协议编程.http协议编程.远程控制技术.木马技术.模拟键盘和鼠标技术.网页游戏辅助程序设计技术等. <C#网络编程高级篇之网

程序性能优化之网络传输与数据存储优化(五)下

阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680 本篇文章将继续从7Z极限压缩和WebP使用来介绍网络传输与数据存储优化: 一.7Z极限压缩 一些文件过大或者是容量太大了,占用硬盘太多空间了.此刻可以使用压缩软件进行压缩,让它的体积变小了.其中极限压缩可以让文件夹或者是文件,压缩的最小.那么如何使用这个极限压缩功能的. ? 1.你要到网上下载这个压缩的程序,点击它,点击[install]. ? ? 2.此刻软件

Python之路【第十七篇】:Django【进阶篇 】

Python之路[第十七篇]:Django[进阶篇 ] Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去调用数据访问层执行数据库操作 import MySQLdb def GetList(sql): db = MySQLdb.connect(user='root', db='wupeiqidb', passwd='1234', host='localhost')

Android网络传输中必用的两个加密算法:MD5 和 RSA (附java完成测试代码)

MD5和RSA是网络传输中最常用的两个算法,了解这两个算法原理后就能大致知道加密是怎么一回事了.但这两种算法使用环境有差异,刚好互补. 一.MD5算法 首先MD5是不可逆的,只能加密而不能解密.比如明文是yanzi1225627,得到MD5加密后的字符串是:14F2AE15259E2C276A095E7394DA0CA9  但不能由后面一大串倒推出yanzi1225627.因此可以用来存储用户输入的密码在服务器上.现在下载文件校验文件是否中途被篡改也是用的它,原理参见:http://blog.c