<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    weidagang2046的專欄

    物格而后知致
    隨筆 - 8, 文章 - 409, 評論 - 101, 引用 - 0
    數據加載中……

    UNIX環境下如何應用消息隊列實現進程間通信

    一、 引 言

    ---- 進 入 九 十 年 代 后, 隨 著 計 算 機 和 網 絡 技 術 的 發 展, 很 多 數 據 處 理 系 統 都 采 用 開 放 系 統 結 構 的 客 戶 機/ 服 務 器 網 絡 模 式。 即 客 戶 機 提 出 任 務 請 求, 由 服 務 器 做 相 應 處 理, 執 行 被 請 求 的 任 務, 然 后 將 結 果 返 回 給 客 戶 機。 例 如: 銀 行ATM 的 前 置 機 和 數 據 處 理 的 主 機 之 間 即 構 成 客 戶 機/ 服 務 器 模 式; 電 話 銀 行 的 前 置 機 和 銀 行 數 據 處 理 主 機 之 間 也 構 成 這 種 模 式 結 構。 還 有POS 等。 這 樣, 各 種 應 用 的 請 求 是 很 頻 繁 的, 數 據 主 機 在 處 理 通 存 通 兌, ATM, 電 話 銀 行, POS 等 各 種 請 求 時, 如 果 沒 有 相 應 機 制 的 控 制, 數 據 將 出 現 混 亂, 有 可 能 產 生 透 支, 也 有 可 能 處 理 密 碼 已 改 變 的 帳 戶.。 數 據 的 完 整 性, 安 全 性 無 法 控 制。 而 消 息 隊 列 正 是 解 決 這 一 問 題 的 有 力 工 具。 它 使 主 機 在 處 理 各 種 請 求 時, 按 照 先 后 順 序 有 條 不 紊 地 進 行, 保 證 了 數 據 的 一 致 性 和 安 全 性。

    二、 基 本 概 念

    ---- 1. 隊 列

    ---- 隊 列 是 信 息 的 線 性 表, 它 的 訪 問 次 序 是 先 進 先 出(FIFO)。 也 就 是 說, 置 入 隊 列 中 的 第 一 個 數 據 項 將 是 從 隊 列 中 第 一 次 讀 出 的 數 據 項, 置 入 的 第 二 項 將 是 讀 出 的 第 二 項, 依 此 類 推。 這 是 隊 列 允 許 的 唯 一 存 取 操 作, 其 它 隨 機 訪 問 是 不 允 許 的。 這 種 數 據 結 構 保 證 對 數 據 資 源 的 請 求 將 嚴 格 按 照 先 后 順 序 進 行, 因 而 可 用 于 對 事 件 的 調 度 并 起 到I/O 緩 沖 的 作 用。

    ---- 2. 報 文

    ---- 發 送 進 程 和 接 收 進 程 進 行 信 息 的 交 換, 一 般 是 通 過 將 信 息 劃 分 為 若 干 段 放 入 數 據 交 換 緩 沖 器 中, 進 程 間 通 過 對 該 緩 沖 器 的 存 取 來 實 現 通 信。 因 此, 數 據 是 以 不 連 續 的 形 式 在 進 程 間 傳 送, 這 些 不 連 續 的 部 分 就 叫 報 文。

    ---- 3. 消 息 隊 列

    ---- 將 報 文 按 隊 列 的 結 構 進 行 組 織 就 叫 消 息 隊 列。 該 隊 列 用 于 存 放 正 被 發 送 或 接 收 的 每 一 個 報 文 的 標 題 信 息。 每 一 個 消 息 隊 列 還 對 應 有 一 個 數 據 結 構, 它 含 有 消 息 隊 列 的 存 取 權 限, 和 消 息 隊 列 的 當 前 狀 態 信 息 等 信 息。 消 息 隊 列 可 進 行" 發 送" 和" 接 收" 操 作。

    三、 消 息 隊 列 的 編 程 要 點 及 運 作 過 程

    ---- 1. 消 息 隊 列 的 創 建

    ---- 在 報 文 能 夠 發 送 和 接 收 之 前, 必 須 創 建 一 個 能 夠 唯 一 被 識 別 出 的 消 息 隊 列 和 數 據 結 構, 這 個 被 創 建 的 唯 一 標 識 符 叫 做 消 息 隊 列 描 述 符(msqid), 用 來 識 別 或 引 用 相 關 的 消 息 隊 列 和 數 據 結 構。 用msgget(long key, int msgflg) 系 統 調 用 來 創 建 消 息 隊 列, 其 中 key 是 一 個 長 整 型, 可 由 用 戶 設 定 也 可 通 過ftok() 獲 得。msgflg 的 值 是 八 進 制 的 消 息 隊 列 操 作 權 和 控 制 命 令 的 組 合。 操 作 權 定 義 為:

    操作允許權 八進制整數

    用戶可讀 0400

    用戶可寫 0200

    同組可讀 0040

    同組可寫 0020

    其它可讀 0004

    其它可寫 0002


    ---- 操 作 權 可 相 加 而 派 生, 如 用 戶 可" 讀"、" 寫" 的 權 限 為0400|0200=0600。 控 制 命 令 可 取IPC_CREAT 或IPC_EXCL。 如 果 要 創 建 一 個key=888 且 屬 主 和 同 組 可 讀 寫 的 消 息 隊 列, 執 行 以 下 系 統 調 用msgget(0x888,0660|IPC_CREAT)。 創 建 后 可 用ipcs 命 令 看 到 以 下 信 息:


    IPC status from /dev/mem as of Sun

    Jan 25 06:49:52 1970

    T ID KEY MODE OWNER GROUP

    Message Queues:

    . q 7 0x00000888 --rw-rw----

    root system

    ...


    ---- 它 的 消 息 隊 列 描 述 符 是7, 屬 主 是root , 同 組 是system, 存 取 權 是 屬 主、 用 戶 可 讀 寫。 如 果 執 行msgget(0x888,0660|IPC_CREAT) 時, 與0x888 對 應 的 消 息 隊 列 已 存 在, 則 返 回 該 消 息 隊 列 的 描 述 符msqid。
    ---- 2. 消 息 的 發 送

    ---- 消 息 隊 列 一 經 創 建 即 可 用msgsnd(int msqid, void *msgp, size_t msgsz, int msgflg) 發 送 消 息。msgqid 是 經msgget 創 建 的 消 息 隊 列 描 述 符,msgp 是 指 向 消 息 段 的 指 針, 該 指 針 所 指 結 構 含 有 報 文 類 型 和 要 發 送 或 接 收 的 報 文:

    struct msgbuf {

    long mtype;/*消息類型*/

    char mtext[512];

    /* 消息正文,512暫定為消息段的大小*/

    }

    ---- msgsz 是msgp 參 量 指 向 的 數 據 結 構 中 字 符 數 組 的 長 度, 即 報 文 長 度, 最 大 值 由MSGMAX 確 定。msgflg 是 當 消 息 隊 列 滿 時( 隊 列 中 無 空 閑 空 間), 系 統 要 采 取 的 行 動. 如 果msgflg&IPC_NOWAIT= 真, 調 用 進 程 立 即 返 回, 不 發 送 該 消 息。 如 果msgflg&IPC_NOWAIT= 假, 調 用 進 程 暫 停 執 行, 處 于" 掛 起" 狀 態, 且 不 發 送 該 消 息。 直 到 下 列 情 況 之 一 出 現:
    ---- - 引 起 暫 停 的 條 件 不 再 存 在, 如 隊 列 出 現 空 閑, 即 可 發 送
    ---- - 該 消 系 隊 列 被 從 系 統 中 刪 去
    ---- - 調 用 進 程 接 收 到 一 個 要 捕 捉 的 信 號, 如 中 斷 信 號, 此 時 不 發 送 消 息, 調 用 進 程 按signal 中 描 述 的 方 式 執 行。

    ---- 如 果msgsnd 返 回0 則 發 送 成 功。 返 回-1 則 表 示 發 送 失 敗, 錯 誤 類 型 可 具 體 查 看errno。

    ---- 3. 消 息 的 接 收

    ---- 用 msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg) 系 統 調 用 從 msqid 消 息 隊 列 中 讀 取 一 條 信 息 并 將 其 放 入 消 息 段 指 針msgp 指 向 的 結 構。msgsz 給 出mtext 的 字 節 數, 如 果 所 接 收 的 消 息 比msgsz 大 且msgflg&MSG_NOERROR 為 真, 則 按msgsz 的 大 小 截 斷 而 不 通 知 調 用 進 程。msgtyp 指 定 要 求 的 消 息 類 型:

    ---- msgtyp=0 接 收 消 息 隊 列 中 的 第 一 個 報 文
    ---- msgtyp >0 接 收 消 息 隊 列 中 的 類 型 為msgtyp 的 第 一 個 報 文
    ---- msgtyp< 0 接 收 消 息 隊 列 中 小 于 等 于msgtyp 絕 對 值 的 最 低 類 型 的 第 一 個 報 文

    ---- 當 隊 列 上 沒 有 所 期 望 類 型 的 消 息 或 消 息 隊 列 為 空 時msgflg 指 出 調 用 進 程 要 采 取 的 行 動: 如 果msgflg&IPC_NOWAIT 為 真, 則 調 用 進 程 立 即 結 束 并 返 回-1。 如msgflg&IPC_NOWAIT 為 假, 則 調 用 進 程 暫 停 執 行 直 至 出 現:

    ---- - 隊 列 中 放 入 所 需 類 型 的 消 息, 調 用 進 程 接 收 該 消 息
    ---- -msqid 消 息 隊 列 從 系 統 中 刪 除
    ---- - 調 用 進 程 接 收 到 捕 獲 的 信 號, 此 時 不 接 收 消 息, 調 用 進 程 按signal 描 述 的 方 式 執 行。

    ---- 如 果msgrev 執 行 成 功, 則 返 回 放 入mtext 中 的 字 節 數, 失 敗 返 回-1 , 錯 誤 類 型 可 查errno。

    ---- 4. 消 息 隊 列 的 控 制 和 撤 銷

    ---- 用 msgctl(int msqid, int cmd, struct msqid_ds *buf) 系 統 調 用 實 現 對 消 息 隊 列 的 控 制。msgqid 必 須 是 用msgget 創 建 的 消 息 隊 列 描 述 符。cmd 可 以 是:

    ---- IPC_STAT 查 看 消 息 隊 列 的 狀 態, 結 果 放 入buf 指 針 指 向 的 結 構
    ---- IPC_SET 為 消 息 隊 列 設 置 屬 主 標 識, 同 組 標 識, 操 作 允 許 權, 最 大 字 節 數
    ---- IPC_RMID 刪 除 指 定 的msqid 以 及 相 關 的 消 息 隊 列 和 結 構

    四、 編 程 示 例

    ---- 下 面 給 出 一 個 運 用 消 息 隊 列, 實 現 進 程 通 信 的 實 例。 以 下 程 序 在 IBM RS/6000 小 型 機(AIX 操 作 系 統) 上 和IBM PC(UNIX 操 作 系 統) 上 分 別 調 試 通 過。 該 程 序 主 要 模 擬 根 據 帳 號 查 詢 余 額 的 過 程。 包 括 三 方 面:

    請 求 進 程 從 標 準 輸 入 讀 入 帳 號, 并 將 該 帳 號 通 過 消 息 隊 列 發 送 給 服 務 進 程;

    服 務 進 程 接 收 該 帳 號 后, 按 照 請 求 的 先 后 順 序 在 標 準 輸 入 上 輸 入 該 帳 戶 的 姓 名 和 余 額, 并 將 結 果 返 回 給 客 戶 進 程;

    請 求 進 程 接 收 返 回 的 信 息, 并 將 結 果 輸 出 在 標 準 輸 出 上。
    ---- 服 務 進 程(msgcenter) 先 于 請 求 進 程(msgreq) 啟 動. 客 戶 進 程 啟 動 時 要 攜 帶 請 求 編 號, 可 同 時 起 動 多 個 請 求 進 程。


    /*請求方程序msgreq.c*/

    #include

    #include

    #include

    #include

    #include

    static struct msgbuf1{

    long mtype;

    char mtext[100];

    } sndbuf, rcvbuf, *msgp ;

    extern int errno;

    main(int argc, char **argv)

    { int rtrn, msqid ;

    char name[10];

    double balance;

    if (argc!=2){ fprintf(stderr,

    "msgreq [01-99]\n"); exit(-1); }

    if ( (msqid = msgget(0x888, IPC_CREAT|0660)) == -1 ){

    fprintf(stderr, "msgget 888 failed !\n"); exit(-1);

    }

    msgp=&sndbuf;

    sprintf(sndbuf.mtext,"%2.2s",argv[1]);

    printf("輸入4位帳號:");

    scanf("%s",&sndbuf.mtext[2]);

    sndbuf.mtext[6]=0;

    msgp->mtype=666;

    rtrn=msgsnd(msqid,msgp, strlen(sndbuf.mtext), 0);

    if (rtrn==-1){

    perror("msgsnd"); exit(-1);

    }

    msgp=&rcvbuf;

    fprintf(stderr,"等待后臺數據處理進程的回答....");

    rtrn=msgrcv(msqid,msgp, 100, atoi(argv[1]), 0);

    if(rtrn==-1){ perror("msgrcv"); exit(-1); }

    sscanf(rcvbuf.mtext,"%[^|]|%lf",name,&balance);

    printf("\n姓名=%s\n",name);

    printf("余額=%lf\n",balance);

    }

    /*服務方程序msgcenter.c*/

    #include

    #include

    #include

    #include

    #include

    static struct msgbuf1{

    long mtype;

    char mtext[100];

    } sndbuf, rcvbuf , *msgp;

    extern int errno;

    main()

    { int rtrn, msgqid ;

    char strbuf[100];

    if ( (msqid = msgget(0x888, IPC_CREAT|0600)) == -1 ){

    fprintf(stderr, "msgget 888 failed !\n"); exit(-1);

    }

    while(1) {

    msgp=&rcvbuf;

    fprintf(stderr,"等待前臺進程的請求....");

    rtrn=msgrcv(msqid, msgp, 100, 666 ,MSG_NOERROR);

    if(rtrn==-1){ perror("msgrcv");exit(-1); }

    msgp=&sndbuf;

    sprintf(strbuf,"%2.2s\0",rcvbuf.mtext);

    msgp->mtype=atoi(strbuf);

    printf("\n輸入帳號=%4.4s的帳戶姓名:",&rcvbuf.mtext[2]);

    scanf("%s",sndbuf.mtext);

    strcat(sndbuf.mtext,"|");

    printf("輸入該帳戶余額:");

    scanf("%s",strbuf);

    strcat(sndbuf.mtext,strbuf);

    rtrn=msgsnd(msqid,msgp, strlen(sndbuf.mtext), 0);

    if (rtrn==-1){ perror("msgsnd"); exit(-1); }

    }

    }

    轉自:http://fanqiang.chinaunix.net/program/other/2001-07-06/2147.shtml

    posted on 2005-08-04 12:55 weidagang2046 閱讀(677) 評論(0)  編輯  收藏 所屬分類: Linux

    主站蜘蛛池模板: 亚洲精品中文字幕无乱码麻豆| 亚洲国产精品网站久久| 3344免费播放观看视频| 免费夜色污私人影院网站| 亚洲欧洲AV无码专区| 亚洲精品人成电影网| 久久久无码精品亚洲日韩蜜臀浪潮| 亚洲第一成人影院| 伊在人亚洲香蕉精品区麻豆| 日韩免费在线观看| 免费观看四虎精品国产永久| 日本无吗免费一二区| 免费在线观看日韩| 亚洲精品无码久久不卡| 亚洲精品无码久久久久sm| 又大又硬又爽免费视频| ZZIJZZIJ亚洲日本少妇JIZJIZ| 国产综合精品久久亚洲| 久久www免费人成看片| 久久久久国产精品免费免费搜索 | 国产l精品国产亚洲区在线观看| a级亚洲片精品久久久久久久| 国产v亚洲v天堂无码网站| 911精品国产亚洲日本美国韩国| 亚洲国产成人精品无码区在线秒播| 亚洲欧美日韩中文高清www777| 亚洲精品无码中文久久字幕| 羞羞视频在线观看免费| 嫩草成人永久免费观看| 欧美大尺寸SUV免费| 亚洲国产精品VA在线看黑人| 涩涩色中文综合亚洲| 免费看一区二区三区四区| 在线看片无码永久免费视频| 久久久久亚洲爆乳少妇无| 亚洲精品福利网泷泽萝拉| 一级一看免费完整版毛片| 亚洲免费闲人蜜桃| 亚洲香蕉网久久综合影视| 亚洲av永久无码一区二区三区| a毛片在线还看免费网站|