并发编程-单元练习题

Posted foremostxl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了并发编程-单元练习题相关的知识,希望对你有一定的参考价值。

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

中断是指在计算机执行期间,系统内发生任何非寻常的或非预期的急需处理事件,使得cpu暂时中断当前正在执行的程序,
转去执行相应的事件处理程序。待处理完毕后又返回原来被中断处继续执行或调度新的进程执行的过程。
它使计算机可以更好更快利用有限的系统资源解决系统响应速度和运行效率的一种控制技术。
实时响应,系统调度。

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

内核态:cpu可以访问内存的所有数据,包括外围设备,例如硬盘,网卡,cpu也可以将自己从一个程序切换到另一个程序。
用户态:只能受限的访问内存,且不允许访问外围设备,占用cpu的能力被剥夺,cpu资源可以被其他程序获取。
为什么要有用户态和内核态?
    由于需要限制不同的程序之间的访问能力,防止他们获取别的程序的内存数据,或者获取外围设备的数据,并发送到网络,
    cpu划分出两个权限等级:用户态和内核态。

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

进程指:正在执行的一个程序或者说一个任务,负责执行任务的是cpu。进程是用来把资源集中到一起的,进程是资源单位,或者说资源集合。

进程间通信(IPC)
消息队列(    队列 = 管道 + 锁)
管道(使用消息传递的)
有名管道(FIFO)
信号量
共享内存
套接字(socket)

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

管道通常指无名管道
1、它是半双工的(即数据只能在一个方向上流动),具有固定的读端和写端
2、它只能用于具有亲缘关系的进程中通信(也就是父与子进程或者兄弟进程之间)
3、数据不可反复读取了,即读了之后欢喜红区中就没有了
消息队列
1、消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级
2、消息队列独立于发送与接收进程。进程终止时,消息队列及其内容不会被删除。
3、消息队列可以实现消息随机查询。
 
    队列 = 管道 + 锁

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

队列,信号量(Semaphore),Event事件,定时器Timer,线程queue,进程池和线程池,异步调用+回调机制

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

同步I/O操作:实际的I/O操作将导致请求进程阻塞,直到I/O操作完成。

异步I/O操作:实际的I/O操作不导致请求进程阻塞。

 

同步或者异步I/O主要是指访问数据的机制(即实际I/O操作的完成方式),

同步 一般指主动请求并等待I/O操作完毕的方式,I/O操作未完成前,会导致应用进程挂起;

而异步 指用户进程触发IO操作以后便开始做自己的事情,而当IO操作已经完成的时候会得到IO

完成的通知(异步的特点就是通知),这可以使进程在数据读写时也不阻塞。

 

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

python 多进程通信Queue Pipe Value Array
queue和pipe用来在进程间传递消息;
Value + Array 是python中共享内存映射文件的方法;速度比较快.

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

Python multiprocessing.Manager(进程间共享数据)
Python中进程间共享数据,除了基本的queue,pipe和value+array外,还提供了更高层次的封装。使用multiprocessing.Manager可以简单地使用这些高级接口。
Manager支持的类型有list,dict,Namespace,Lock,RLock,Semaphore,BoundedSemaphore,Condition,Event,Queue,Value和Array。

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

from threading import Thread,currentThread
import datetime,time
def print_time():
    time_now = datetime.datetime.now()
    print(currentThread().getName(),time_now)
if __name__ == __main__:
    time.sleep(10)
    for i in range(10):
        t = Thread(target=print_time)
        t.start()

Thread-1 2018-10-03 17:46:20.225000
Thread-2 2018-10-03 17:46:20.226000
Thread-3 2018-10-03 17:46:20.227000
Thread-4 2018-10-03 17:46:20.227000
Thread-5 2018-10-03 17:46:20.228000
Thread-6 2018-10-03 17:46:20.229000
Thread-7 2018-10-03 17:46:20.229000
Thread-8 2018-10-03 17:46:20.230000
Thread-9 2018-10-03 17:46:20.230000
Thread-10 2018-10-03 17:46:20.231000

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

 方法一、用线程池的方法

技术分享图片
from threading import Thread
from threading import currentThread
from concurrent.futures import ThreadPoolExecutor
import time
import random
 
def task():
    print(currentThread().getName())
    time.sleep(random.randint(1,3))
 
if __name__ == __main__:
    pool = ThreadPoolExecutor(5)
    for i in range(10):
        pool.submit(task)

ThreadPoolExecutor-0_1 2018 10 03 20:37:30
ThreadPoolExecutor-0_0 2018 10 03 20:37:30
ThreadPoolExecutor-0_2 2018 10 03 20:37:30
ThreadPoolExecutor-0_3 2018 10 03 20:37:30
ThreadPoolExecutor-0_4 2018 10 03 20:37:30

ThreadPoolExecutor-0_0 2018 10 03 20:37:32
ThreadPoolExecutor-0_1 2018 10 03 20:37:32
ThreadPoolExecutor-0_3 2018 10 03 20:37:32
ThreadPoolExecutor-0_4 2018 10 03 20:37:32
ThreadPoolExecutor-0_2 2018 10 03 20:37:32
4.002999782562256
View Code

方法二、用信号量的方法(Semaphore)

技术分享图片
from threading import Thread, Semaphore, currentThread
import time


def task():
    sm.acquire()
    print(currentThread().getName())
    time.sleep(2)
    sm.release()


if __name__ == __main__:
    sm = Semaphore(5)
    start = time.time()
    for i in range(10):
        t = Thread(target=task)
        t.start()
    t.join()
    stop = time.time()
    print(stop - start)

Thread-1
Thread-2
Thread-3
Thread-4
Thread-5
Thread-6
Thread-7
Thread-9
Thread-8
Thread-10
4.001999855041504
View Code

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

技术分享图片
def start():
    count = 3
    while count > 0:
        name = input(>>).strip()
        pwd = input(>>).strip()
        if len(pwd) >= 6 and pwd[0].isalpha():# isalpha() 方法检测字符串是否只由字母组成。
            pwd_md5 = hashlib.md5(pwd.encode(utf-8)).hexdigest()
            print(输入成功)
            obj = {user_name: name, pass_word: pwd_md5}
            with open(password.txt,a,encoding=utf-8)as f:
                json.dump(obj,f)
            exit()
        else:
            if count == 0:
                print(三次错误)
                exit()
            count -=1
            print(f输入错误还有{count}次机会)
            continue

if __name__ == __main__:
    import hashlib,json
    start()
View Code

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

python中的socketserver模块,主要是用来提供服务器类,并且提供异步处理的能力。

服务端:
import socketserver
class Handler(socketserver.BaseRequestHandler):
    def handle(self):
        print(new connection:, self.client_address)
        while True:
            try:
                data = self.request.recv(1024)
                if not data: break
                print(client data:, data.decode())
                self.request.send(data.upper())
            except Exception as e:
                print(e)
                break


if __name__ == "__main__":
    server = socketserver.ThreadingTCPServer((127.0.0.1, 8082), Handler)
    server.serve_forever()

客户端
模拟多个线程 ---客户端发送消息

 def start(ip_port):
    client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    client.connect(ip_port)
    client.send(f"{currentThread().getName()} hello".encode(utf-8))
    data = client.recv(1024)
    print(data.decode(utf-8))

if __name__ == __main__:
    import socket
    from threading import Thread,currentThread
    ip_port = (127.0.0.1,8082)
    for i in range(20):
        t = Thread(target=start,args=(ip_port,))
        t.start()

 

以上是关于并发编程-单元练习题的主要内容,如果未能解决你的问题,请参考以下文章

JUC并发编程 共享模式之工具 JUC CountdownLatch(倒计时锁) -- CountdownLatch应用(等待多个线程准备完毕( 可以覆盖上次的打印内)等待多个远程调用结束)(代码片段

golang代码片段(摘抄)

《java并发编程实战》

练习题|并发编程

JUC并发编程 -- JUC介绍 & 线程/进程 & 并发/并行 & Java代码查看CPU的核数

Java并发编程实战 04死锁了怎么办?