热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

理解python并发编程_python并发编程相关概念总结

1、简述计算机操作系统中的“中断”的作用?中断是指在计算机执行期间,系统内发生任何非寻常的或非预期的急需处理事件,使得CPU暂时中断当前正

1、简述计算机操作系统中的“中断”的作用?

中断是指在计算机执行期间,系统内发生任何非寻常的或非预期的急需处理事件,使得CPU暂时中断当前正在执行的程序而转去执行相应的时间处理程序。

待处理完毕后又返回原来被中断处继续执行或调度新的进程执行的过程。

当遇到IO操作时或一个进程运行时间过长或被更高的优先级的进程替代时出现中断。有利于合理利用有限的系统资源,提高程序运行效率。

2、简述计算机内存中的“内核态”和“用户态”;

处于用户态的程序只能访问用户空间,而处于内核态的程序可以访问用户空间和内核空间。

当一个任务(进程)执行系统调用而陷入内核代码中执行时,我们就称进程处于内核运行态(或简称为内核态)。此时处理器处于特权级最高的(0级)内核代码中执行。当进程处于内核态时,执行的内核代码会使用当前进程的内核栈。每个进程都有自己的内核栈。

当进程在执行用户自己的代码时,则称其处于用户运行态(用户态)。此时处理器在特权级最低的(3级)用户代码中运行。

用户态切换到内核态的3种方式:1、系统调用:这是用户态进程主动要求切换到内核态的一种方式2、异常3、外围设备的中断

3、进程间通信方式有哪些?

进程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。

IPC的方式通常有:管道(包括无名管道和命名管道)、消息队列、信号量、共享存储、Socket、Streams等。其中 Socket和Streams支持不同主机上的两个进程IPC。

4、简述你对管道、队列的理解;

管道:通常指无名管道

它是半双工的(即数据只能在一个方向上流动),具有固定的读端和写端。

它只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间)。

它可以看成是一种特殊的文件,对于它的读写也可以使用普通的read、write 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。

队列:是消息的链接表。一个消息队列由一个标识符(即队列ID)来标识。

消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级。

消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除。

消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取。

队列和管道都是将数据存放于内存中,而队列是基于“管道+锁”实现的。

5、请列举你知道的进程间通信方式;

1.管道(无名管道):速度慢,容量有限,只有父子进程能通讯。它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。它是半双工的(即数据只能在一个方向上流动),具有固定的读端和写端。2.FIFO(命名管道):任何进程间都能通讯,但速度慢,它是一种文件类型。3.消息队列:是消息的链接表,存放在内核中。消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除,所以要注意第一次读的时候,要考虑上一次没有读完数据的问题。容量受到系统限制。消息队列可以实现消息的随机查询4.信号量:信号量用于实现进程间的互斥与同步,而不是用于存储进程间通信数据。5.共享内存区:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一个进程要注意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以用作线程间通讯,不过没这个必要,线程间本来就已经共享了同一进程内的一块内存

信号量+共享内存通常结合在一起使用,信号量用来同步对共享内存的访问。

6、什么是同步I/O,什么是异步I/O?

Stevens给出的定义(其实是POSIX的定义)是这样子的:

A synchronous I/O operation causes the requesting process to be blocked until that I/O operationcompletes;

An asynchronous I/O operation does notcause the requesting process to be blocked;

同步IO:当程序发生IO操作时,会将进程阻塞,直到IO操作完成才能继续执行后面的代码。如:blocking IO,non-blocking IO,IO multiplexing。

异步IO:进程不会发生阻塞。如:asynchronous IO。

7、请问multiprocessing模块中的Value、Array类的作用是什么?举例说明它们的使用场景

使用Value或者Array把数据存储在一个共享的内存表中,用于实现进程间共享状态。

Value( typecode, arg1, … argN, lock )

在共享内容中常见ctypes对象。typecode要么是包含array模块使用的相同类型代码(如’i’,’d’等)的字符串,要么是来自ctypes模块的类型对象(如ctypes.c_int、ctypes.c_double等)。

所有额外的位置参数arg1, arg2 ….. argN将传递给指定类型的构造函数。lock是只能使用关键字调用的参数,如果把它置为True(默认值),将创建一个新的锁定来包含对值的访问。

如果传入一个现有锁定,比如Lock或RLock实例,该锁定将用于进行同步。如果v是Value创建的共享值的实例,便可使用v.value访问底层的值。例如,读取v.value将获取值,而赋值v.value将修改值。

RawValue( typecode, arg1, … ,argN)

同Value对象,但不存在锁定。

Array( typecode, initializer, lock )

在共享内存中创建ctypes数组。typecode描述了数组的内容,意义与Value()函数中的相同。initializer要么是设置数组初始大小的整数,要么是项目序列,其值和大小用于初始化数组。lock是只能使用关键字调用的参数,意义与Value()函数中相同。

如果a是Array创建的共享数组的实例,便可使用标准的python索引、切片和迭代操作访问它的内容,其中每种操作均由锁定进行同步。对于字节字符串,a还具有a.value属性,可以吧整个数组当做一个字符串进行访问。

RawArray(typecode, initializer )

同Array对象,但不存在锁定。当所编写的程序必须一次性操作大量的数组项时,如果同时使用这种数据类型和用于同步的单独锁定(如果需要的话),性能将得到极大的提升。

#进程间共享状态,当然尽最大可能防止使用共享状态,但最终有可能会使用到.#1-共享内存#可以通过使用Value或者Array把数据存储在一个共享的内存表中

from multiprocessing importProcess,Value,Arrayimporttimedeff(n, a, name):

time.sleep(1)

n.value= name *namefor i inrange(len(a)):

a[i]= -i

process_list=[]if __name__ == '__main__':

num= Value('d',0.0) #d表示一个双精浮点类型

arr = Array('i',range(10)) #i表示一个带符号的整型

for i in range(10):

p= Process(target=f,args=(num, arr, i))

p.start()

process_list.append(p)for j inprocess_list:

j.join()print(num.value)print(arr[:])#更加灵活的共享内存可以使用multiprocessing.sharectypes模块

View Code

https://blog.csdn.net/winterto1990/article/details/48106505

8、请问multiprocessing模块中的Manager类的作用是什么?与Value和Array类相比,Manager的优缺点是什么?

使用Value或者Array把数据存储在一个共享的内存表中。

Manager()返回一个manager类型,控制一个server process,可以允许其它进程通过代理复制一些python objects。

支持:list,dict,Namespace,Lock,Semaphore,BoundedSemaphore,Condition,Event,Queue,value,Array ;

Manager 提供了多进程环境中共享数据的使用的方案, 共享数据可以支持跨进程, 甚至跨机器访问, 以网络通信的方式实现(eg: unix socket, tpc),一个 manager 实例控制一个 server 进程(manager 自己创建的后台进程,对用户透明), 该 server 负责管理共享数据. 其他进程则是用户业务创建的,它们可以通过代理方式来访问 manager 自带 server 的共享数据. 代理可以理解为一个网络通道, 业务进程 和 manager server 进程通信交互数据, 由于server 单线程, 对业务进程通信请求FIFO的方式来处理数据, 因此保证了操作行为的可预期性(当然如果业务进程希望锁定数据, 可以通过代理的 Lock 锁机制来实现).

manger的的优点是可以在poor进程池中使用,缺点是windows下环境下性能比较差,因为windows平台需要把Manager.list放在if name='main'下,而在实例化子进程时,必须把Manager对象传递给子进程,否则lists无法被共享,而这个过程会消耗巨大资源,因此性能很差。

https://www.cnblogs.com/shengyang17/p/8987075.html

9、写一个程序,包含十个线程,子线程必须等待主线程sleep 10秒钟之后才执行,并打印当前时间;

importtimefrom threading importThread, currentThreaddeftask():print("current time:", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))if __name__ == "__main__":

t_l=[]for i in range(10): #开启10个线程

t = Thread(target=task)

t_l.append(t)for t int_l:

time.sleep(10)

t.start()

View Code

10、写一个程序,包含十个线程,同时只能有五个子线程并行执行;

importtimeimportrandomfrom threading importThread, currentThread, Semaphoredeftask():

sm.acquire()print("%s is running" %currentThread().getName())

time.sleep(random.randint(1, 3))

sm.release()if __name__ == "__main__":

sm= Semaphore(5)for i in range(10):

t= Thread(target=task, name="线程%s" %i)

t.start()

View Code

11、写一个程序,要求用户输入用户名和密码,要求密码长度不少于6个字符,且必须以字母开头,如果密码合法,则将该密码使用md5算法加密后的十六进制概要值存入名为password.txt的文件,超过三次不合法则退出程序;

importhashlibimportredefregister():

i= 1

while i <&#61; 3:

username&#61; input("username:").strip()

password&#61; input("password:").strip()if len(password) >&#61; 6 and re.search("\A[a-zA-Z]", password):

m&#61;hashlib.md5()

m.update(password.encode("utf-8"))

md5&#61;m.hexdigest()

with open("password.txt", "a", encoding&#61;"utf-8") as f:

f.write("%s,%s" %(username, md5))print("注册成功&#xff01;")break

else:print("密码长度不少于6个字符&#xff0c;且必须以字母开头")

i&#43;&#61; 1

if __name__ &#61;&#61; "__main__":

register()

View Code

12、写一个程序&#xff0c;使用socketserver模块&#xff0c;实现一个支持同时处理多个客户端请求的服务器&#xff0c;要求每次启动一个新线程处理客户端请求&#xff1b;

服务端&#xff1a;

#基于socketserver的进程间并发通信

importsocketserverclassServer(socketserver.BaseRequestHandler):"""服务端"""

def handle(self): #必须定义一个名为handle的方法

"""处理与客户端的交互"""

while True: #循环接收和发送消息

msg &#61; self.request.recv(1024) #收消息

if notmsg:break

print("from %s: %s" % (self.client_address, msg.decode())) #客户端地址信息和消息

self.request.send(msg.upper()) #发送消息给客户端

if __name__ &#61;&#61; "__main__":

server_addr&#61; ("127.0.0.1", 8080)

server&#61; socketserver.ThreadingTCPServer(server_addr, Server) #实现多线程的socket通话

print("server starting.....")

server.serve_forever()#当一个客户端链接断开后继续循环接收其他客户端链接

View Code

客户端&#xff1a;

classClient:"""客户端"""

def __init__(self, ip, port):

self.sock&#61;socket.socket(socket.AF_INET, socket.SOCK_STREAM)

self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)

self.sock.connect((ip, port))defhandle_msg(self):"""发送、接收消息"""

whileTrue:

msg&#61; input(">>>").strip()if notmsg:breakself.sock.send(msg.encode())

data&#61; self.sock.recv(1024)print("from server:", data.decode())if __name__ &#61;&#61; "__main__":

client&#61; Client("127.0.0.1", 8080)print("server connecting.....")

client.handle_msg()

View Code

https://www.cnblogs.com/xiajie/p/5250675.html

https://www.cnblogs.com/progor/p/8617042.html



推荐阅读
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文介绍了在mac环境下使用nginx配置nodejs代理服务器的步骤,包括安装nginx、创建目录和文件、配置代理的域名和日志记录等。 ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
author-avatar
手机用户2502876961
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有