6.進程間通訊

一.基本概念
 進程間通訊:進程之間交換數據的過程叫進程間通訊。
 進程間通訊的方式:、
 
  簡單的進程間通訊:
   
   命令行:父進程經過exec函數建立子進程時能夠附加一些數據
   環境變量表:父進程經過exec函數建立子進程順便傳遞一張環境變量表
    信號:父子進程之間能夠根據進程號相互發送信號,進程簡單通訊
   文件:一個進程向文件中寫入數據,另外一個進程從文件中讀取出來。
  命令行,環境變量只能單向傳遞,信號太過於簡單,文件通訊不能實時。
  XSI通訊方式:X/open 計算機制造商組織。
   共享內存,消息隊列,信號量,
  網絡進程間通訊方式:
   網絡通訊就是不一樣機器的進程間通訊方式
傳統的進程間通訊方式:管道
二.管道
  1.管道是一種古老的通訊方式(基本上再也不使用)
  2.早期的管道是一種半雙工,如今大多數是全雙工的
  3.有名管道(管道是以文件的方式存在的)
   建立管道文件:
    命令mkfifo
    函數mkfifo
    #include <sys/types.h>
          #include <sys/stat.h>
          int mkfifo(const char *pathname, mode_t mode);
        管道通訊的編程模式:
         進程A 進程B
         建立管道mkfifo
         打開管道文件open 打開管道
         寫/讀數據write/read 讀/寫數據
         關閉管道close 關閉管道
        4.無名管道:由內核幫助建立,只返回管道的文件描述符,看不到管道文件,這種管道只能用於fork建立的父子進程之間
          int pipe(int pipefd[2]);
          pipefd[0]用來讀數據
          pipefd[1]用來寫數據
          練習:使用無名管道讓父子進程通訊
三.XSI IPC進程間通訊
 1.XSI通訊是依靠內核的IPC對象進程通訊
 
 2.每個IPC對象都有一個IPC標識(相似文件描述符),IPC標識符是一個非負整數。
 3.IPC對象必需要先建立,建立後才能進程獲取,設置,操做,刪除。
 4.建立IPC對象必需要提供一個鍵值(key_t),鍵值是建立獲取IPC對象的依據
 5.產生鍵值的方法:
  固定的字面值:1980014
 
  使用函數計算:ftok(項目路徑,項目id)
  使用宏讓操做系統隨機分配:IPC_PRIVTE
   必須把獲取到的IPC對象標識符記錄下來,告訴其餘進程
 6.XSI能夠建立的IPC對象有:
  共享內存,消息隊列,信號量
四.共享內存
 1.由內核維護一塊共享的內存區域,其餘進程把本身的虛擬地址映射到這塊內存,而後多個進程之間共享這塊內存了。
 2.這種進程間通訊的好處是不須要信息複製 ,它是進程間通訊最快的一種方式
 3 .這種方式會面臨同步的問題,須要與其餘的通訊方式配合,最合適的方式就是信號。
 共享內存的編程模式:
  1.進程之間要約定一個鍵值
  進程A 進程B
  建立共享內存
  加載共享內存 加載共享內存
  卸載共享內存 卸載共享內存
  銷燬共享內存
     int shmget(key_t key, size_t size, int shmflg);
     功能:建立共享內存
     size:大小
     模式:
     返回值:IPC對象標識符(相似於文件描述符)
     void *shmat(int shmid, const void *shmaddr, int shmflg);
     功能:加載共享內存()
     
     shmid:shmget的返回值
     
     shmaddr:進程提供的虛擬地址,也能夠爲NULL,若是爲空,操做系統會自動選擇一塊地址映射
     
     shmflg:
      SHM_RDONLY:映射內存的權限爲只讀
      SHM_REMAP:映射已經存在的內存共享
      SHM_RND:當shmaddr爲空時自動分配
      mode_flag:權限
 int shmdt(const void *shmaddr);
 功能:這個地址對應的共享內存取消映射關係
 #include <sys/ipc.h>
    #include <sys/shm.h>
    int shmctl(int shmid, int cmd, struct shmid_ds *buf);
    功能:控制/銷燬共享內存
    cmd:
     IPC_STAT:獲取共享內存的屬性
     IPC_SET:設置共享內存的屬性
     IPC_RMID:刪除共享內存
    buf:
     記錄共享內存屬性的對象
五.消息隊列
 1. 消息隊列是一個由系統內核負責存儲和管理,並經過IPC對象標識符獲取的數據鏈表
    #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/msg.h>
       int msgget(key_t key, int msgflg);
       msgflg:
        建立IPC_CREAT | IPC_EXCL
        獲取:0
    int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
        功能:向消息隊列發送消息
       
        msqid:msgget的返回值
        msgp:消息(消息類型+消息內容)的首地址
        msgsz:消息內容的長度(不包含消息類型)
        msgflg:
         
    ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
                      int msgflg);
       功能:從消息隊列接收消息
       
       msgp:存儲消息的緩衝區
       
       msgsz:要接收的消息長度
       
       msgtyp:要接收消息的類型,(包含在消息的前四個字節)
       
       msgflg:
       
        MSG_NOERROR:當消息的實際長度大於msgsz,則按照msgsz長度截取再發送,不然產生錯a
        MSG_NOWAIT:若是想要接收的消息不存在,則直接返回。
         不然阻塞等待。
        MSG_EXCEPT:從消息隊列中接收第一個不是msgtype類型的第一個消息
    int msgctl(int msqid, int cmd, struct msqid_ds *buf);
    功能:控制/銷燬消息隊列
    cmd:
     IPC_STAT:獲取消息隊列的屬性
     IPC_SET:設置消息隊列的屬性
     IPC_RMID:刪除消息隊列
六.IPC相關命令:
 ipcs -m 查看共享內存
 ipcrm -m id 刪除共享內存
 ipcs -q 查看消息隊列
 ipcrm -q id 刪除消息隊列
七.信號量
  信號量(信號燈),能夠看成進程與進程之間共享的全局變量,通常用來爲共享的資源計數
 信號量的使用方法:
  1.進程A,建立信號量,並設置信號量的初始值(設置資源數)
  2.進程B,獲取信號量,查看信號量(查詢剩餘資源的數量),減小信號量(使用資源),增長信號量(資源使用完畢歸還)
  3.當一個進程減小信號量時,若是不能減(資源使用完畢),則進程能夠進入等待狀態,當信號量可以被減的時候(其餘進程把資源還回來了),進程會被喚醒
    #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/sem.h>
       int semget(key_t key, int nsems, int semflg);
       功能:建立獲取獲取信號量
       nsems:信號量的數量
       semflg:
         IPC_CREAT
         IPC_EXCL
         0644之類的權限碼
       int semop(int semid, struct sembuf *sops, unsigned nsops);
       功能:對信號量增長或減小
       struct sembuf {
          unsigned short sem_num;
          short sem_op;
          short sem_flg; // IPC_NOWAIT標識不阻塞
       }
       int semctl(int semid, int semnum, int cmd, ...);
       功能:對信號量的控制或釋放
       semnum:信號量的編號
       cmd:
         IPC_SET 設置信號量的屬性
         IPC_STAT 設置信號量的屬性
         IPC_RMID 刪除信號量
         IPC_INFO 獲取信號量的信息
相關文章
相關標籤/搜索