python并发编程相关概念总结

一、简述计算机操做系统中的“中断”的做用?html

中断是指在计算机执行期间,系统内发生任何非寻常的或非预期的急需处理事件,使得CPU暂时中断当前正在执行的程序而转去执行相应的时间处理程序。
待处理完毕后又返回原来被中断处继续执行或调度新的进程执行的过程。 当遇到IO操做时或一个进程运行时间过长或被更高的优先级的进程替代时出现中断。有利于合理利用有限的系统资源,提升程序运行效率。

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

处于用户态的程序只能访问用户空间,而处于内核态的程序能够访问用户空间和内核空间。 当一个任务(进程)执行系统调用而陷入内核代码中执行时,咱们就称进程处于内核运行态(或简称为内核态)。此时处理器处于特权级最高的(0级)内核代码中执行。当进程处于内核态时,执行的内核代码会使用当前进程的内核栈。每一个进程都有本身的内核栈。 当进程在执行用户本身的代码时,则称其处于用户运行态(用户态)。此时处理器在特权级最低的(3级)用户代码中运行。 用户态切换到内核态的3种方式: 1、系统调用:这是用户态进程主动要求切换到内核态的一种方式 2、异常 三、外围设备的中断

三、进程间通讯方式有哪些?算法

进程间通讯(IPC,InterProcess Communication)是指在不一样进程之间传播或交换信息。 IPC的方式一般有:管道(包括无名管道和命名管道)、消息队列、信号量、共享存储、Socket、Streams等。其中 Socket和Streams支持不一样主机上的两个进程IPC。

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

  管道:一般指无名管道 它是半双工的(即数据只能在一个方向上流动),具备固定的读端和写端。 它只能用于具备亲缘关系的进程之间的通讯(也是父子进程或者兄弟进程之间)。 它能够当作是一种特殊的文件,对于它的读写也可使用普通的read、write 等函数。可是它不是普通的文件,并不属于其余任何文件系统,而且只存在于内存中。   队列:是消息的连接表。一个消息队列由一个标识符(即队列ID)来标识。 消息队列是面向记录的,其中的消息具备特定的格式以及特定的优先级。 消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除。 消息队列能够实现消息的随机查询,消息不必定要以先进先出的次序读取,也能够按消息的类型读取。   队列和管道都是将数据存放于内存中,而队列是基于“管道+锁”实现的。

五、请列举你知道的进程间通讯方式;数组

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

六、什么是同步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 not cause the requesting process to be blocked; 同步IO:当程序发生IO操做时,会将进程阻塞,直到IO操做完成才能继续执行后面的代码。如:blocking IO,non-blocking IO,IO multiplexing。 异步IO:进程不会发生阻塞。如:asynchronous IO。

七、请问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 import Process,Value,Array import time def f(n, a, name): time.sleep(1) n.value = name * name for i in range(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 in process_list: j.join() print(num.value) print(arr[:]) # 更加灵活的共享内存可使用multiprocessing.sharectypes模块
View Code

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

八、请问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并发

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

import time from threading import Thread, currentThread def task(): 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 in t_l: time.sleep(10) t.start()
View Code

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

import time import random from threading import Thread, currentThread, Semaphore def task(): 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

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

import hashlib import re def register(): i = 1
    while i <= 3: username = input("username:").strip() password = input("password:").strip() if len(password) >= 6 and re.search("\A[a-zA-Z]", password): m = hashlib.md5() m.update(password.encode("utf-8")) md5 = m.hexdigest() with open("password.txt", "a", encoding="utf-8") as f: f.write("%s,%s" % (username, md5)) print("注册成功!") break
        else: print("密码长度很多于6个字符,且必须以字母开头") i += 1


if __name__ == "__main__": register()
View Code

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

服务端:

# 基于socketserver的进程间并发通讯
import socketserver class Server(socketserver.BaseRequestHandler): """服务端"""
    def handle(self):  # 必须定义一个名为handle的方法
        """处理与客户端的交互"""
        while True:  # 循环接收和发送消息
            msg = self.request.recv(1024)  # 收消息
            if not msg: break
            print("from %s: %s" % (self.client_address, msg.decode()))  # 客户端地址信息和消息
            self.request.send(msg.upper())  # 发送消息给客户端


if __name__ == "__main__": server_addr = ("127.0.0.1", 8080) server = socketserver.ThreadingTCPServer(server_addr, Server)  # 实现多线程的socket通话
    print("server starting.....") server.serve_forever() # 当一个客户端连接断开后继续循环接收其余客户端连接
View Code

客户端:

class Client: """客户端"""
    def __init__(self, ip, port): self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.sock.connect((ip, port)) def handle_msg(self): """发送、接收消息"""
        while True: msg = input(">>>").strip() if not msg: break self.sock.send(msg.encode()) data = self.sock.recv(1024) print("from server:", data.decode()) if __name__ == "__main__": client = 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

相关文章
相关标签/搜索