linux處理序間通訊總結

來源:互聯網
上載者:User

轉自:http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=4077304

1、linux進程間通訊
        繼承unix進程間通訊:管道 訊號
        AT&T :system V IPC 通訊進程只能在單個電腦 :訊號量  訊息佇列 共用記憶體
        BSD:形成了基於socket的進程間通訊機制 TCP/IP
2、管道
        (1)無名管道:父子進程
                 #include <unistd.h>

                 int pipe(int pipefd[2]);
                 建立一個管道
                 fd[0]:讀端
                 fd[1]:寫端
                傳回值:
                        0:成功
                        -1:失敗
                注意:(1)當管道已經滿了 write pipe 會阻塞
                       (2) 當管道為空白   read pipe 會阻塞

                        
        (2)有名管道:任何進程之間
        #include <sys/types.h>
        #include <sys/stat.h>
                int mkfifo(const char *pathname, mode_t mode);
3、訊號
        訊號在軟體層次上對中斷的一種類比 非同步通訊方式
        中斷:對cpu上的中斷 (硬體)
        訊號:對進程的中斷 (軟體)
        (1)訊號的來源
                (1)程式執行錯誤 如 記憶體訪問越界
                (2)其他進程發送
                (3)通過控制終端發送 ctrl + c;
                (4)子進程結束向父進程發送訊號 SIGCLD
                (5)定時器SIGALRM
        (2)訊號
                kill -l 查看當前系統所有的訊號
        (3)訊號處理方式
                忽略訊號:對訊號不做任何處理
                捕捉訊號:定義處理函數 當訊號發生的時候 執行相應的處理函數  
                預設操作:在linux系統中間都規定了預設操作
        (4)訊號的發送與捕捉
                 #include <sys/types.h>
                 #include <signal.h>

                int kill(pid_t pid, int sig);
                        pid:接受訊號的進程的PID
                        sig:訊號
                傳回值:0:成功
                        -1:出錯
                 int raise(int sig);
                 //kill(getpid(),SIGSTOP);
                    給進程本身發送訊號

        (5)定時器的訊號捕捉        
                unsigned int alarm(unsigned int seconds);
                進程定時器
                定時時間到 發送SIGALRM
                SIGALRM:預設操作:終止進程
                傳回值:
                        在調用之前 如果已經設定過鬧鐘 返回上一次的剩餘時間
                        否則返回0
                        -1:出錯
                int pause(void);
                暫停進程
                當收到訊號時 會喚醒進程繼續執行
        (6)訊號處理
                #include <signal.h>
                typedef void (*sighandler_t)(int);

                sighandler_t signal(int signum, sighandler_t handler);
        
                參數:
                        signum:訊號
                        handler:SIG_IGN:忽略該訊號
                                SIG_DFL:採用預設處理訊號
                                自訂的訊號處理函數的指標
                傳回值:返回一個指向訊號處理函數的地址

                1)父進程捕捉子進程的訊號
                2)從終端輸入文字再次輸出到終端,如果3s沒有輸入就輸出提示
                        //SIGALRM
                        alarm()和signal()
4、訊號的阻塞處理        
        (1)通知系統核心停止向進程發送指定的訊號        
        (2)核心對進程接收到的相應的訊號進行緩衝
       (3)當進程解除相應的訊號的阻塞 

        設定阻塞的原因:
                (1)正在執行訊號處理函數時有其他的訊號到來
                (2)訊號處理函數和其他進程對某個共用地區進行讀寫 
                sigset_t:訊號集
          int sigemptyset(sigset_t *set);
          把訊號集合清空

          int sigfillset(sigset_t *set);
          把訊號集合填滿 
          int sigaddset(sigset_t *set, int signum);
          把對應的訊號加到阻塞訊號集合中

          int sigdelset(sigset_t *set, int signum);
          把對應的訊號從阻塞訊號集合中刪除        
          int sigismember(const sigset_t *set, int signum);
          判斷訊號是否是在阻塞訊號集合中
          int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
          //設定阻塞訊號集合

          how:設定訊號阻塞掩碼的方式
                          SIG_BLOCK:阻塞訊號集
                        SIG_UNBLOCK:解除訊號集
                        SIG_SETMASK:設定阻塞掩碼
         oldset:舊的阻塞集合
         int sigpending(sigset_t *set);
         //擷取阻塞的訊號 未決訊號

        int flag = 0;
        int flag = 1;
        while(flag == 0){
          int sigsuspend(const sigset_t *mask);
        }
          //等待訊號  
          (1)設定訊號掩碼並阻塞進程
         (2)收到訊號 恢複原來的屏蔽字
          (3)調用進程設定的訊號處理函數
         (4)等待訊號處理函數返回後 sigsuspend()返回
          原子操作
          pause() -----等待訊號(阻塞的訊號除外)
5、訊息佇列
        (1)訊息的列表
                隊列ID
                訊息ID
         (2)建立
                 #include <sys/types.h>
                #include <sys/ipc.h>
                #include <sys/msg.h>

                int msgget(key_t key, int msgflg);
                key:指定的ID來產生隊列ID key:ftok()通過轉換檔來擷取
                msgflg:IPC_CREAT:建立新的訊息佇列
                       IPC_EXCL:存在報錯
                       IPC_NOWAIT:非阻塞
                傳回值:返回隊列ID
                #include <sys/types.h>
                #include <sys/ipc.h>

                    key_t ftok(const char *pathname, int proj_id);
                    功能:擷取key
                    pathname:檔案名稱---->inode節點號
                    proj_id:自己指定

                    由inode節點號和proj_id合成

                    65538:0x10002  
                    
                    38:0x26

                   key: 0x2610002

        (4)接收訊息
                 ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
                 參數:
                         msqid:訊息佇列ID ----- msgget()
                        msgp:訊息的緩衝區
                        msgsz:訊息結構的大小
                        msgtyp:0:接收訊息佇列中的第一個訊息
                               大於0:接收訊息佇列中第一個為msgtyp的訊息
                               小於0:接收訊息佇列中第一個不小於msgtyp的絕對值由最小的訊息
                        msgflg:
                                0:忽略
                                MSG_NOERROR:接收的訊息大於size 則訊息就會截短到size位元組 不通知訊息發送進程
                                IPC_NOWAIT:沒有指定類型的訊息 就會返回錯誤ENOMSG
                傳回值:實際接收的位元組數
                        會刪除對應的訊息
        (5)發送訊息
                 int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
                 參數:
                         msqid:訊息佇列ID ----- msgget()
                        msgp:發送的訊息緩衝區
                        struct msgbuf{
                                long mtype;//訊息類型
                                char mtext[1];//訊息內容
                        };
                        msgsz:訊息內容的大小
                        msgflg:
                                IPC_NOWAIT:發送條件不滿足的時 就會立即返回

                                a):隊列訊息已經滿了
                
        建立2個子進程 父進程負責發送 子進程1:發送類型為1的訊息        子進程2:發送訊息類型為2的訊息
        子進程1接收類型為1的訊息
        子進程2接收類型為2的訊息

                
        (5)控制函數
          int msgctl(int msqid, int cmd, struct msqid_ds *buf);

          msqid:訊息佇列ID
          cmd:
                  IPC_STAT:擷取struct msqid_ds結構 儲存到buf
                IPC_SET:設定struct msgqid_ds結構
                IPC_RMID:刪除訊息佇列
           buf:儲存struct msqid_ds結構

          傳回值:成功:0(IPC_STAT,IPC_SET,IPC_RMID)
                    失敗:-1

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.