在unix程序中涉及多個使用者id和使用者組id,包括如下:
有效使用者id為root的程序稱為特權程序;
一些有關聯的程序組可以形成乙個會話,下面函式用於建立乙個會話:
#include
pid_t setsid(void);
該函式不能由程序組的首領程序呼叫,否則產生錯誤。對於非首領程序,呼叫該函式不僅建立新會話,還有如下作用:
後台化的步驟:
bool daemonize()
else
if(pid > 0)
//設定檔案許可權掩碼,當程序建立新檔案時,檔案的許可權將是mode & 0777
umask(0);
pid_t sid = setsid();
if(sid < 0)
//切換工作目錄
if(chdir("/") < 0)
close(stdin_fileno);
close(stdout_fileno);
close(stderr_fileno);
//關閉其他已開啟的檔案描述符,**省略
//將標準輸入,標準輸出,標準錯誤輸出都重定向到/dev/null檔案
open("/dev/null", o_rdonly);
open("/dev/null", o_rdwr);
open("/dev/null", o_rdwr);
return
true;
}
守護程序詳細說明
reactor模式
reactor:要求主線程只負責監聽檔案描述符上是否有事件發生,有的話就立即將該事件通知工作執行緒,除此之外,主線程不做任何其他實質性工作,讀寫資料,接收新的連線,以及處理客戶請求均在工作執行緒完成。
proactor模式
與reactor模式不同,proactor模式將所有i/o操作都交給主線程和核心來處理,工作執行緒僅僅負責業務邏輯,因此,proactor模式更符合伺服器程式設計框架。
使用非同步i/o模型(以aio_read和aio_write)實現proactor模式的工作流程:
1) 主線程呼叫aio_read函式向核心註冊socket上的讀完成事件,並告訴核心使用者讀緩衝區的位置,以及讀操作完成時如何通知應用程式(以訊號為例);
2) 主線程繼續處理其他邏輯;
3) 當socket上的資料被讀入使用者緩衝區,核心將向應用程式傳送乙個訊號,以通知應用程式資料可用;
4)應用程式預定義好的訊號處理函式選擇乙個工作執行緒來處理客戶請求,工作執行緒處理完客戶請求之後,呼叫aio_write函式向核心註冊socket上的寫完成事件,並告訴核心使用者緩衝區的位置,以及寫操作完成時如何通知應用程式(以訊號為例);
5)主線程繼續處理其他邏輯;
6)當使用者緩衝區的資料被寫入socket之後,核心將向應用程式傳送乙個訊號,以通知應用程式資料已經傳送完畢;
7)應用程式預定義好的訊號處理函式選擇乙個工作執行緒來做善後處理,比如決定是否關閉socket;
模擬proactor模式
使用同步i/o模擬proactor模式的一種方法,原理:主線程執行資料讀寫操作,讀寫完成之後,主線程向工作執行緒通知這一「完成事件」,那麼從工作執行緒角度來看,其直接獲得了資料讀寫的結果,接下來要做的只是對讀寫的結果進行邏輯處理;
工作流程:
1) 主線程往epoll核心時間表註冊socket上的讀就緒事件;
2) 主線程呼叫epoll_wait等待socket上有資料可讀;
3) 當socket上有資料可讀,epoll_wait通知主線程,主線程從從socket迴圈讀取資料,知道沒有更多資料可讀,然後將讀取到的資料封裝成乙個請求物件插入請求佇列;
4) 睡眠在請求佇列上的某個工作執行緒被喚醒,它獲得請求物件並處理客戶請求,然後往epoll核心事件表註冊socket上的寫就緒事件;
5) 主線程呼叫epoll_wait等待socket可寫;
6) 當socket可寫時,epoll_wait通知主線程,主線程往socket上寫入伺服器處理客戶請求的結果;
流程圖:
併發程式設計的目的是讓程式「同時」執行多個任務:
如果是計算密集型的,併發程式設計沒有優勢,反而由任務的切換導致效率降低;
如果程式是i/o密集型的,比如經常讀寫檔案,訪問資料庫等,則情況就不同了,由於i/o操作的速度遠沒有cpu計算的速度快,所以讓程式阻塞於i/o操作將浪費大量的cpu時間,如果程式有多個執行程序,則當前被i/o操作所阻塞的執行執行緒可主動放棄cpu(或由os排程),並將執行權轉移到其他執行緒,這樣一來,cpu就可以用來做更加有意義的事情(除非所有執行緒都同時被i/o操作所阻塞),而不是等待i/o操作完成,因此cpu的利用率顯著提公升;
半同步半非同步模式
半同步半非同步模式中的同步和非同步與i/o模式中的同步和非同步是完全不同的概念。
在半同步半非同步模式中,同步執行緒用於處理客戶邏輯,非同步執行緒用於處理i/o事件,非同步執行緒監聽到客戶請求後,就將其封裝成請求物件並插入請求佇列中,請求佇列將通知某個工作在同步模式的工作執行緒讀取並處理該請求物件,具體選擇哪個工作執行緒來為新的客戶請求服務,取決於請求佇列的設計;
半同步半反應堆模式:使用模擬的proactor時間處理模式,主線程完成資料的讀寫,主線程一般會將應用程式資料、任務型別等資訊封裝成乙個任務物件,將其(或指向任務佇列的指標)插入請求佇列,工作執行緒從請求佇列中取得任務物件之後,即可直接處理之,無需讀寫操作了。
但有如下缺點:
影響伺服器效能的首要因素是系統的硬體資源,比如cpu的個數、速度、記憶體的大小等;
從「軟環境」提公升伺服器的效能,「軟環境」:
池
「浪費」伺服器的硬體資源,以換取其執行效率,這就是池的概念。
池是一組資源的集合,這組資源在伺服器啟動之初就被完全建立好並初始化,稱為靜態資源分配;
當伺服器進入正式執行階段,即開始處理客戶請求的時候,如果它需要相關的資源,可直接從池中獲取,無須動態分配。直接從池中獲取所需資源比動態分配資源的速度快的多,因為分配系統資源的系統呼叫時很耗時的。當伺服器處理完乙個客戶連線之後,可以把相關的連線放入池中,無須執行系統呼叫釋放資源。
池相當於伺服器管理系統資源的應用層設施,避免了伺服器對核心的頻繁訪問;
資料複製
高效能伺服器應該避免不必要的資料複製,尤其是當資料複製發生在使用者**和核心之間的時候。可以使用「零拷貝」函式進行資料的複製,如sendfile等;
使用者**內部(不訪問核心)的資料複製也應該避免,可以使用共享記憶體共享資料而不是使用管道或訊息佇列傳遞資料;
上下文切換和鎖
併發程式必須考慮上下文切換的問題,即程序切換或執行緒切換導致的系統開銷。即使是i/o密集型的伺服器,也不應該使用過多的工作執行緒(或工作程序),否則執行緒間的切換將占用大量的cpu時間,伺服器真正用處理業務邏輯的cpu時間的比重就顯得不足了。
多執行緒伺服器的乙個優點:不同執行緒可以同時執行在不同的cpu上,當執行緒的數量不大於cpu的數目時,上下文切換就不是問題了。
併發程式需要考慮的另外乙個問題是共享資源的加鎖保護,鎖通常被認為是導致伺服器效率低下的乙個因素,因為由它引入的**不僅不處理任何業務邏輯,而且需要訪問核心資源。因此,伺服器如果有更好的解決方案,應該避免使用鎖。當伺服器必須使用鎖,則可以考慮減小鎖的粒度;
伺服器規範
1 分割槽規範 1.1web伺服器 卷標 容量 mb 捲組 vg 邏輯卷 lv boot 100mb swap 4g 30g vg01 lvroot www 剩餘空間 vg01 lvmydata 1.2mysql伺服器 卷標 容量 mb 捲組 vg 邏輯卷 lv boot 100mb swap 4g...
伺服器巡檢規範
1.檢查伺服器運 況,記憶體負載,儲存負載,cpu負載,網路負載,負載過高時進行資源釋放操作,或者對資源進行擴容 2.檢查機房伺服器以及儲存上的硬碟指示燈,報紅或報黃時,排查原因,若硬碟損壞或將要損壞,應及時對相應硬碟進行更換 3.檢查機房溫度,確保機房空調的製冷以及送風功能正常,檢查機房濕度,確保...
伺服器巡檢規範
伺服器巡檢規範 01.伺服器主機巡檢規範 02.伺服器日常巡檢細則 03.管理員賬號管理規範 04.使用者伺服器系統使用規範 05.機房來訪人員管理規範 06.主機防火牆管理規範 07.組織容器命名規範 08.伺服器主機名命名規範 01.伺服器主機巡檢規範 1.檢查伺服器運 況,記憶體負載,儲存負載...