天天看點

資訊安全系統設計基礎第十二周學習總結

第十二章 并發程式設計

并發指邏輯控制流在時間上是重疊的

程序:

  • 每個控制流都是一個程序
  • 是由核心來排程維護
  • 有獨立的虛拟位址空間
  • 在與其他流進行通信時,控制流必須使用某種顯式的程序間通信機制

    I/O多用複路:

  • 在并發程式設計中,應用程式在一個程序的上下文中顯式的排程它們自己的邏輯流
  • 所有流都共享同一個位址空間

    線程:

  • 是運作在單一程序上下文中的邏輯流
  • 由核心進行排程
  • 是程序和I/O多用複路的混合體

基于程序的并發程式設計

資訊安全系統設計基礎第十二周學習總結
資訊安全系統設計基礎第十二周學習總結
資訊安全系統設計基礎第十二周學習總結

基于程序的并發伺服器

由于伺服器運作時間長,是以要包括一個SIGCHLD程序程式,用來回收僵死子程序的資源

資訊安全系統設計基礎第十二周學習總結

關于程序的優劣

對于父,子程序:共享檔案表,但不共享使用者位址空間

基于I/O多用複路的并發程式設計

基本思路:使用select函數,要求核心挂起程序,隻有在一個或多個I/O事件發生後,才将控制傳回應用的程式

例如:

資訊安全系統設計基礎第十二周學習總結

select函數處理類型為fd_set的集合

被允許對描述符集合做的三件事:

  1. 配置設定他們
  2. 将一個此種類型的變量指派給另一個變量
  3. 用FD_ZERO,FD_SET,FD_CLR和FD_ISSET宏指令來修改和檢查他們

    select的兩個輸入:

  4. 讀集合的描述輸入(fdset)
  5. 讀集合的基數(n)

    副作用:select修改了參數fdset指向的fd_set,指明讀集合中一個稱為準備好集合的子集

利用select實作一個疊代echo伺服器:

資訊安全系統設計基礎第十二周學習總結
資訊安全系統設計基礎第十二周學習總結
資訊安全系統設計基礎第十二周學習總結

一旦select傳回,就用FD_ISSET宏指令來判斷哪個可以進行讀了

基于I/O多用複路的并發事件驅動伺服器

一個狀态機就是一組狀态,輸入事件和轉移,其中轉移就是将狀态和輸入事件映射到狀态

自循環同一個輸入和輸出之間的轉換

資訊安全系統設計基礎第十二周學習總結
  • select函數檢測到輸入事件
  • add_client函數建立一個新的邏輯流
  • check_clients函數通過回送輸入行來執行狀态轉移

伺服器使用I/O多用複,借助select函數檢測輸入事件的發生

資訊安全系統設計基礎第十二周學習總結

clientfd數組表示已連接配接描述符的集合,其中整數-1表示一個可用的槽位

資訊安全系統設計基礎第十二周學習總結
資訊安全系統設計基礎第十二周學習總結

I/O多用複路技術的優劣:

優點:

  1. 它比基于程序的設計給程式員更多的對程式行為的控制
  2. 一個基于I/O多用複路用事件驅動伺服器是運作在一個單一程序上下文,并每個邏輯流都能通路該程序的全部位址空間

    缺點:

  • 編碼複雜

基于線程的并發程式設計

每個線程都有它自己的線程上下文,包括一個唯一的整數線程ID,棧,棧指針,程式計數器,通用目的寄存器和條件碼

線程執行模型

主線程:每個程序開始生命周期都是單一線程

某時刻,主線程建立一個對等線程,從此時開始,兩個線程并發運作

線程和程序的差別:

  • 一個線程的上下文比一個程序的上下文小很多
  • 線程上下文的切換要比程序上下文的切換快很多
  • 程序是按照嚴格的父子層次來組織的,線程則是對等的池
    資訊安全系統設計基礎第十二周學習總結

Posix線程

  • 建立線程
    資訊安全系統設計基礎第十二周學習總結
    資訊安全系統設計基礎第十二周學習總結
  • 終止線程
  1. 當頂層的線程例程傳回時,線程會隐式地終止
  2. 通過調用pthread_exit函數,線程會顯式地終止
    資訊安全系統設計基礎第十二周學習總結
  3. 某個對等線程調用Unix的exit函數,該函數終止程序以及與該程序相關的所有線程
  4. 另一個對等線程通過目前線程ID作為參數調用pthread_cancle函數來終止目前線程
    資訊安全系統設計基礎第十二周學習總結
  • 回收已終止線程的資源
    資訊安全系統設計基礎第十二周學習總結
    pthread_join函數會堵塞,直到線程tid終止,将線程例程傳回的(void)指針指派為pthread_return指向的位置,然後回收*已終止線程占用的所有儲存器資源
  • 分離線程

    在任意一個時間點上,線程是可結合的或者是分離的

    資訊安全系統設計基礎第十二周學習總結
  • 初始化線程
    資訊安全系統設計基礎第十二周學習總結

多線程程式中的共享變量

通常,線程的寄存器是從不共享的,而虛拟儲存器總是共享的

将變量映射到存儲器

  • 全局變量:是定義在函數之外的變量,任何線程都可以引用
  • 本地自動變量:是定義在函數内部但是沒有static屬性的變量
  • 本地靜态變量:是定義在函數内部并有static屬性的變量

共享變量

若說變量v是共享的,當且僅當它的一個執行個體被一個以上的線程引用

用信号量同步線程

在共享變量的同時引入了同步錯誤的可能性

一般而言,沒有辦法預測作業系統是否能為你的線程選擇一個正确的順序

進度圖

進度圖将n個并發線程的執行模型化為一條n維笛卡爾空間中的軌迹線

資訊安全系統設計基礎第十二周學習總結

圖的原點對應于沒有任何線程完成一條指令的初始狀态

資訊安全系統設計基礎第十二周學習總結

在進度圖中,兩個臨界區的交集形成的狀态空間區域稱為不安全區

信号量

資訊安全系統設計基礎第十二周學習總結
  • P(s):如果s是非零的,那麼P将s減1,并且立即傳回。若s為零,則挂起這個線程,直到s非零
  • V(s):V操作将s加1
資訊安全系統設計基礎第十二周學習總結

使用信号量來實作互斥

基本思想:将每個共享變量與一個信号量s聯系起來,然後用P(s)和V(s)操作将相應的臨界區包圍起來

資訊安全系統設計基礎第十二周學習總結

利用信号量來排程共享資源

生産者-消費者問題

資訊安全系統設計基礎第十二周學習總結
資訊安全系統設計基礎第十二周學習總結
資訊安全系統設計基礎第十二周學習總結
資訊安全系統設計基礎第十二周學習總結

基于預線程化的并發伺服器

資訊安全系統設計基礎第十二周學習總結

使用線程提高并行性

最簡單的方法:将序列劃分成t個不相交區域,然後給t個不同的線程每個配置設定一個區域

資訊安全系統設計基礎第十二周學習總結

并行程式的加速比:

資訊安全系統設計基礎第十二周學習總結
資訊安全系統設計基礎第十二周學習總結
資訊安全系統設計基礎第十二周學習總結

其他并發問題

線程安全

四個線程不安全函數類:

  • 不保護共享變量的函數
  • 保持跨越多個調用的狀态的函數
  • 傳回指向靜态變量指針的函數
  • 調用線程不安全函數的函數

可重入性

資訊安全系統設計基礎第十二周學習總結

線上程化的程式中使用已存在的函數庫

資訊安全系統設計基礎第十二周學習總結

競争

當一個程式的正确性一個線程要在另一個線程到達y點之前到達它的控制流中的x點時,就會發生競争

死鎖

資訊安全系統設計基礎第十二周學習總結

避免死鎖的規則:

互斥鎖加鎖順序規則:如果對于程式中每對互斥鎖(s,t),每個同時占用s和t的線程都按照相同的順序對它們加鎖,那這個程式是無死鎖的

資訊安全系統設計基礎第十二周學習總結