天天看點

Linux 程序學習

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>

                    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);

                        msgp:發送的消息緩沖區

                        struct msgbuf{

                                long mtype;//消息類型

                                char mtext[1];//消息内容

                        };

                        msgsz:消息内容的大小

                                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

繼續閱讀