信號量

一,信號量
信號量又稱爲信號燈,它是用來協調不同進程間的數據對象的,而最主要的應用是共享內存方式的進程間通信。本質上,信號量是一個計數器,它用來記錄對某個資源(如共享內存)的存取狀況。一般說來,爲了獲得共享資源,進程需要執行下列操作:
   (1) 測試控制該資源的信號量。
   (2) 若此信號量的值爲正,則允許進行使用該資源。進程將信號量減1。
   (3) 若此信號量爲0,則該資源目前不可用,進程進入睡眠狀態,直至信號量值大於0,進程被喚醒,轉入步驟(1)。
   (4) 當進程不再使用一個信號量控制的資源時,信號量值加1。如果此時有進程正在睡眠等待此信號量,則喚醒此進程。
   信號量是一個數據集合,用戶可以單獨使用這一集合的每個元素。要調用的第一個函數是semget,用以獲得一個信號量ID。Linux下定義的信號量結構體:

struct semaphore {
        spinlock_t     lock;
        unsigned int   count;
        struct list_head   wait_list;
};

對信號量的操作只能是原子性的操作

二 ,工作原理
信號量只能進行兩種操作等待和發送信號,即P(sv)和V(sv),他們的行爲是這樣的:
P(sv):如果sv的值大於零,就給它減1;如果它的值爲零,就掛起該進程的執行 。
V(sv):如果有其他進程因等待sv而被掛起,就讓它恢復運行,如果沒有進程因等待sv而掛起,就給它加1.

1.semget()函數

int semget(key_t key,int nsems,int semflg); 
功能描述
獲取關聯的信號量集標識。信號量集被建立的情況有兩種:
1.如果值是IPC_PRIVATE。
2.或者值不是IPC_PRIVATE,並且所對應的信號量集不存在,同時標誌中指定IPC_CREAT。
當調用semget創建一個信號量時,他的相應的semid_ds結構被初始化。ipc_perm中各個量被設置爲相應值

2.semctl()函數

int semctl(int sem_id, int sem_num, int command, ...)

3.semop()函數

int semop(int sem_id, struct sembuf *sem_opa, size_t num_sem_ops)
sembuf結構的定義如下:
struct sembuf{  
short sem_num;//除非使用一組信號量,否則它爲0
short sem_op;//信號量在一次操作中需要改變的數據,通常是兩個數,一個是-1,即P(等待)操作,一個是+1,即V(發送信號)操作。
short sem_flg;//通常爲SEM_UNDO,使操作系統跟蹤信號,並在進程沒有釋放該信號量而終止時,操作系統釋放信號量
}; 

三,回滾(ROLLBACK)和撤銷(UNDO)

回滾和前滾是保證Oracle數據庫中的數據處於一致性狀態的重要手段。

在9i版本以前 Oracle使用數據庫中的回滾段來實現未提交數據或因系統故障導致實例崩潰時進行回滾操作 每一個表空間需要創建回滾段,各個表空間對回滾段實現各自的管理 在9i及後續版本 提供了一種新的回滾數據的管理方式,即使用Oracle自動管理的撤銷(Undo)表空間 自動撤銷管理表空間統一管理所有DML的回滾操作,簡化了對於回滾工作的管理 在9i,10g中的回滾段僅僅用作保留向後兼容 撤銷段代替了原有版本中的回滾段,因此本文所有描述均使用撤銷

撤銷的實質意味着將所作的修改退回到修改前的狀態,即倒退所有DML語句

對於任何DML操作而言,必須同時處理數據塊和撤銷塊,並且還會生成重做信息 在ACID中,A、C、I要求生成撤銷,D則要求生成重做 INSERT: 撤銷段記錄插入記錄的rowid,如果需要撤銷,則根據rowid將該記錄刪除即可 UPDATE: 撤銷段記錄被更新字段的原始值,撤銷時將原始值覆蓋新值即可 DELETE: 撤銷段記錄整行的數據,撤銷時執行反向操作將該記錄插入原表 UNDO段中的內容如下: 數據爲修改之前的副本 從每個改變數據的事務中獲得 在事務結束前一直被保留

UNDO段中數據的作用: 用於回滾操作 讀一致性和閃回查詢 用於事務失敗時的恢復

UNDO段與事務: 一個事物的啓動,Oracle將爲其分配僅僅一個UNDO段,若該段用完,則Oracle會自動爲該UNDO段添加另一個區間(extent) 一個UNDO段能夠同時爲多個事務服務

UNDO段與UNDO表空間: UNDO段中的內容存儲在UNDO表空間 任意給定時刻只能使用一個UDNO表空間 UNDO表空間必須被創建爲持久的、本地管理、可自動擴展的表空間 正在使用的UNDO表空間不能撤銷或刪除 UNDO表空間使用循環寫的方式,與聯機日誌文件寫相似,不同的是UNDO中可以設置了undo_retention 保留時間

UNDO段的兩種管理方式: AUTO 自動管理(推薦) MANUAL 手動管理(僅保留)

作者:qq_35032155 發表於2017/6/9 16:58:42 原文鏈接
閱讀:111 評論:0 查看評論
 
[原]進程間通信——共享內存

一, 概念 共享內存:使得多個進程可以訪問同一塊內存空間,是最快的可用IPC形式。是針對 其他通信機制運行效率較低而設計的。往往與其它通信機制,如信號量結合使用, 來達到進程間的同步及互斥。 二,特點 1.共享內存就是允許兩個不相關的進程訪問同一個邏輯內存; 2.共享內存是在兩個正在運行的進程之間共享和傳遞數據的一種最有效的方式; 3.不同進程之間共享的內存通常安排爲同一段物理內存; 4.共享內存不提供任何互斥和同步機制,一般用信號量對臨界資源進行保護; 5.接口簡單

三, 所有進程間通信的特點

1)管道

管道分爲有名管道和無名管道 無名管道是一種半雙工的通信方式,數據只能單向流動,而且只能在具有親緣關係的進程間使用.進程的親緣關係一般指的是父子關係。無明管道一般用於兩個不同進程之間的通信。當一個進程創建了一個管道,並調用fork創建自己的一個子進程後,父進程關閉讀管道端,子進程關閉寫管道端,這樣提供了兩個進程之間數據流動的一種方式。 有名管道也是一種半雙工的通信方式,但是它允許無親緣關係進程間的通信。

2)信號量

信號量是一個計數器,可以用來控制多個線程對共享資源的訪問.,它不是用於交換大批數據,而用於多線程之間的同步.它常作爲一種鎖機制,防止某進程在訪問資源時其它進程也訪問該資源.因此,主要作爲進程間以及同一個進程內不同線程之間的同步手段.

3)消息隊列

消息隊列是消息的鏈表,存放在內核中並由消息隊列標識符標識.消息隊列克服了信號傳遞信息少,管道只能承載無格式字節流以及緩衝區大小受限等特點.消息隊列是UNIX下不同進程之間可實現共享資源的一種機制,UNIX允許不同進程將格式化的數據流以消息隊列形式發送給任意進程.對消息隊列具有操作權限的進程都可以使用msget完成對消息隊列的操作控制.通過使用消息類型,進程可以按任何順序讀信息,或爲消息安排優先級順序.

4)共享內存

共享內存就是映射一段能被其他進程所訪問的內存,這段共享內存由一個進程創建,但多個進程都可以訪問.共享內存是最快的IPC(進程間通信)方式,它是針對其它進程間通信方式運行效率低而專門設計的.它往往與其他通信機制,如信號量,配合使用,來實現進程間的同步與通信.

四 , 共享內存的代碼實現 1. semget函數 創建一個新信號量或取得一個已有信號量

int semget(key_t key, int num_sems, int sem_flags);

2.semctl函數 直接控制信號量信息

int semctl(int sem_id, int sem_num, int command, ...);

3.shmat()函數
第一次創建完共享內存時,它還不能被任何進程訪問,shmat函數的作用就是用來啓動對該共享內存的訪問,並把共享內存連接到當前進程的地址空間。

shm_id:由shmget函數返回的共享內存標識。
shm_addr:指定共享內存連接到當前進程中的地址位置,通常爲空,表示讓系統來選擇共享內存的地址。
shm_flg:是一組標誌位,通常爲0。

4.shmdt()函數
該函數用於將共享內存從當前進程中分離。注意,將共享內存分離並不是刪除它,只是使該共享內存對當前進程不再可用。


發佈了24 篇原創文章 · 獲贊 4 · 訪問量 9030
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章