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

相關文章
相關標籤/搜索