1. 程式人生 > >Linux伺服器多程序模型

Linux伺服器多程序模型

Linux多程序一般是master負責偵聽,worker接受和伺服client。

一個使用了以下技術的多程序模型:

1. sigset:安全訊號,訊號遮蔽和接受。

2. epoll:非同步io模型。

master程序使用訊號模型,偵聽使用者訊號和程式訊號,並和worker交流。它的主迴圈是sigsuspend。

worker程序使用事件模型,使用epoll_wait等待事件,同時他也接受訊號(訊號會中斷epoll_wait)。

  1. // mpserver —— multiple processes server
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <iostream>
  5. usingnamespace std;  
  6. #include <unistd.h>
  7. #include <signal.h>
  8. #include <sys/types.h>
  9. #include <sys/socket.h>
  10. #include <netinet/in.h>
  11. #include <sys/wait.h>
  12. #include <sys/epoll.h>
  13. #include <string.h>
  14. #include <errno.h>
  15. #define err_exit(msg) cout << "[error] " << msg << endl; exit(1)
  16. struct UserOptions{  
  17.     int port;  
  18.     int num_processes;  
  19. };  
  20. void discovery_user_options(int argc, char** argv, UserOptions& options){  
  21.     if(argc <= 2){  
  22.         cout << "Usage: "
     << argv[0] << " <port> <num_processes>" << endl  
  23.             << "port: the port to listen" << endl  
  24.             << "num_processes: the num to start processes. if 0, use single process mode" << endl;  
  25.         exit(1);  
  26.     }  
  27.     options.port = atoi(argv[1]);  
  28.     options.num_processes = atoi(argv[2]);  
  29. }  
  30. int listen_server_socket(UserOptions& options){  
  31.     int serverfd = socket(AF_INET, SOCK_STREAM, 0);  
  32.     if(serverfd == -1){  
  33.         err_exit("init socket error!");  
  34.     }  
  35.     cout << "init socket success! #" << serverfd << endl;  
  36.     int reuse_socket = 1;  
  37.     if(setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, &reuse_socket, sizeof(int)) == -1){  
  38.         err_exit("setsockopt reuse-addr error!");  
  39.     }  
  40.     cout << "setsockopt reuse-addr success!" << endl;  
  41.     sockaddr_in addr;  
  42.     addr.sin_family = AF_INET;  
  43.     addr.sin_port = htons(options.port);  
  44.     addr.sin_addr.s_addr = INADDR_ANY;  
  45.     if(bind(serverfd, (const sockaddr*)&addr, sizeof(sockaddr_in)) == -1){  
  46.         err_exit("bind socket error!");  
  47.     }  
  48.     cout << "bind socket success!" << endl;  
  49.     if(listen(serverfd, 10) == -1){  
  50.         err_exit("listen socket error!");  
  51.     }  
  52.     cout << "listen socket success! " << options.port << endl;  
  53.     return serverfd;  
  54. }  
  55. void signal_handler(int signo){  
  56.     cout << "#" << getpid() << " get a signal:";  
  57.     bool do_exit = false;  
  58.     switch(signo){  
  59.         case SIGCHLD:  
  60.             cout << "SIGCHLD";  
  61.             int status;  
  62.             while(waitpid(0, &status, WNOHANG) > 0){  
  63.             }  
  64.             break;  
  65.         case SIGALRM:  
  66.             cout << "SIGALRM";  
  67.             break;  
  68.         case SIGIO:  
  69.             cout << "SIGIO";  
  70.             break;  
  71.         case SIGINT:  
  72.             cout << "SIGINT";  
  73.             do_exit = true;  
  74.             break;  
  75.         case SIGHUP:  
  76.             cout << "SIGHUP";  
  77.             do_exit = true;  
  78.             break;  
  79.         case SIGTERM:  
  80.             cout << "SIGTERM";  
  81.             do_exit = true;  
  82.             break;  
  83.         case SIGQUIT:  
  84.             cout << "SIGQUIT";  
  85.             do_exit = true;  
  86.             break;  
  87.         case SIGUSR1:  
  88.             cout << "SIGUSR1";  
  89.             break;  
  90.         case SIGUSR2:  
  91.             cout << "SIGUSR2";  
  92.             break;  
  93.     }  
  94.     cout << "!" << endl;  
  95.     if(do_exit){  
  96.         exit(0);  
  97.     }  
  98. }  
  99. void register_signal_handler_imp(int signum, void (*handler)(int)){  
  100.     struct sigaction action;  
  101.     action.sa_handler = handler;  
  102.     sigemptyset(&action.sa_mask);  
  103.     //action.sa_flags = 0;
  104.     if(sigaction(signum, &action, NULL) == -1){  
  105.         err_exit("register signal handler failed!");  
  106.     }  
  107. }  
  108. void register_signal_handler(){  
  109.     register_signal_handler_imp(SIGCHLD, signal_handler);  
  110.     register_signal_handler_imp(SIGALRM, signal_handler);  
  111. 相關推薦

    Linux伺服器程序模型

    Linux多程序一般是master負責偵聽,worker接受和伺服client。 一個使用了以下技術的多程序模型: 1. sigset:安全訊號,訊號遮蔽和接受。 2. epoll:非同步io模型。 master程序使用訊號模型,偵聽使用者訊號和程式訊號,並和worker交流。

    Linux】高併發伺服器模型程序模型執行緒模型

    多程序併發伺服器 使用多程序併發伺服器時要考慮以下幾點:             1.      父程序最大檔案描述個數(父程序中需要close關閉accept返回的新檔案描述符)             2.      系統內建立程序個數(與記憶體大小相關)      

    linux fork程序併發伺服器模型之C/C++程式碼實戰

            在很早的文章中, 我們一起聊過伺服器如何與多個客戶端進行通訊, 那時, 我們要麼用select, 要麼用多執行緒, 卻沒有用多程序。 其實, 多程序也可以實現與多個客戶端進行通訊。          如果是在while中迴圈accept,  然後迴圈處理事情

    Linux網路程式設計【三】:TCP伺服器程序執行緒(http訪問)版本

    為了讓伺服器同時接受多個客戶端訪問,所以需要多程序或者多執行緒 多程序版本: #include<unistd.h> #include<stdio.h> #include<stdlib.h> #include<sys/types.h

    linux伺服器執行緒還是程序的選擇及區別

    轉自http://blog.csdn.net/lishenglong666/article/details/8557215 魚還是熊掌:淺談多程序多執行緒的選擇 關於多程序和多執行緒,教科書上最經典的一句話是“程序是資源分配的最小單位,執行緒是CPU排程的最小單位”,這

    linux socket程序併發伺服器

    /***sever***/ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>

    Linux程式設計——程序程式設計

        本文學習Linux環境下的多程序程式設計,在我之前的文章裡已經講過程序與執行緒。本文,再簡單講一下程序的概念,方便接下來的學習。     程序定義:程序是一個具有一定獨立功能的程式的一次執行活動。     程序狀態圖:

    Linux程式設計 程序執行緒求解PI(圓周率)

    題目: 連結 多程序: #include <unistd.h> #include <stdio.h> #include <stdlib.h> #define n 100000000.0 int main() { i

    Linux程序執行緒之間的區別

    http://blog.csdn.net/byrsongqq/article/details/6339240 網路程式設計中設計併發伺服器,使用多程序與多執行緒 ,請問有什麼區別?  答案一: 1,程序:子程序是父程序的複製品。子程序獲得父程序資料空間、堆和棧的複製品。 2,執行緒:相

    PX4概念學習(1)——Linux程序執行緒基礎

    【學習Freeape大神的uORB時,乘機補補有關Linux多程序、多執行緒的知識】 uORB(Micro Object Request Broker,微物件請求代理器)是PX4/Pixhawk系統中非常重要且關鍵的一個模組,它肩負了整個系統的資料傳輸任務,所有的感測器資料

    Linux程序執行緒基礎

    【學習Freeape大神的uORB時,乘機補補有關Linux多程序、多執行緒的知識】 uORB(Micro Object Request Broker,微物件請求代理器)是PX4/Pixhawk系統中非常重要且關鍵的一個模組,它肩負了整個系統的資料傳輸任務,所有的感測器資料、GPS、PPM訊

    Linux伺服器程序檢視命令詳解

    Linux 伺服器正常啟動後,提供服務時會呼叫程式,佔用程序。這時候我們如何檢視系統中有哪些程序在被呼叫呢?我們可以通過以下命令來檢視。 一、ps 命令 ps 命令是最基本同時也是非常強大的程序檢視命令。使用該命令可以確定有哪些程序正在執行和它所執行的狀態、程序是否結束、程序有沒有僵死、哪些程序

    Linux 實現程序拷貝檔案

    //copy.c #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include<stdlib.h> #include<sys/stat.h> #include<e

    系統技術非業餘研究 » Erlang網路程序模型的實驗

    在做網路程式的時候我們會經常用到多程序模式. 主程序執行bind呼叫得到控制代碼後, 同時fork N個子程序, 把控制代碼傳遞給子程序, 多程序同時accept來處理. 這個模型在erlang下很有現實意義的. 在之前的測試中,我們演示了erlang的單處理器模式的威力,最多的時候在單cpu上可

    併發伺服器--程序實現

    通過簡單的socket可以實現一對一的c/s通訊,當多個客戶端同時進行伺服器訪問,那麼伺服器只能按序的一一進行處理,除了第一個客戶端,其餘客戶端都會陷入等待。並且這樣的程式只能實現半雙工通訊(資料能雙向傳輸,但同一時刻只能單向傳遞,通過切換傳輸方向實現雙工),而且實現方式繁瑣

    [work] Linux Shell程序併發以及併發數控制

    1. 基礎知識準備 1.1. linux後臺程序 Unix是一個多工系統,允許多使用者同時執行多個程式。shell的元字元&提供了在後臺執行不需要鍵盤輸入的程式的方法。輸入命令後,其後緊跟&字元,該命令就會被送往到linux後臺執行,而終端又可以繼續輸入下一個命令了。&nbs

    egg中的程序模型--egg文件搬運工

    egg中的多程序模型 2018年11月19日 多程序間的模型 2018年11月19日 多程序間的模型 Master: 在這個模型下,Master 程序承擔了程序管理的工作(類似 pm2),不

    linux fork 程序建立

    1)fork函式將執行著的程式分成2個(幾乎)完全一樣的程序,每個程序都啟動一個從程式碼的同一位置開始執行的執行緒。 這兩個程序中的執行緒繼續執行,就像是兩個使用者同時啟動了該應用程式的兩個副本。 2)fork函式被呼叫一次但返回兩次。兩次返回的唯一區別是子程序中返回0值而父程序中返回子程序ID。

    Windows 程序模型 摘抄自《windows核心原理與實現》

    3.1.1 多程序模型 現代作業系統總是提供可併發執行多個任務的環境,比如,使用者可以一邊接收電子郵件,一邊聽音樂,還可以同時跟網路上的朋友聊天。但是,現在主流的計算機只有有限的計算資源,例如只有一個單核處理器,較新的個人計算機可能配有一個雙核或四核的處理器。讓一個系統

    linux程序的同步

          linux 多程序的同步:linux多程序我實現同步操作,操作單個訊號量已經不能實現,對多程序的通訊可以採取訊號集的方式,一個訊號集包含了多個訊號量。 首先通過semget()建立訊號量。例如:semid = semget(SEMKEY,2,0600|IFLAG