[C] Review Queue Message

====================

Queue Message 是一種 IPC, 可以運用於不同 Process之間, Message傳遞

====================

  - Linux IPC: Message Queue
    實際運用: 
   1. Send Queue Message
      a. static SYS_QUEUE_ID_T tel_mgr_msg_queue;
          TEL_MGR_EVT_MSG_T evtMsg;
          evtMsg.index = phoneIdx;
          evtMsg.evtType = TEL_MGR_EVT_TYPE_SET_SOUND;
          evtMsg.evtParam.data.setEvtParam.callIdentity = callIdentity;
      b. SYS_QUEUE_Send(tel_mgr_msg_queue, &evtMsg, sizeof(evtMsg), TRUE)
          msgsnd(queueId, temp_pMsg, msgSize, 0);
   2. Receive Queue message
      a. TEL_MGR_EVT_MSG_T evtMsg;
      b. queueRc = SYS_QUEUE_Recv(tel_mgr_msg_queue, &evtMsg, sizeof(evtMsg), TRUE);
      c. 收到 message, 依據不同的 event Type 執行不同事情: 
          switch (evtMsg.evtType)
              case TEL_MGR_EVT_TYPE_SET_SOUND:
              TEL_MGR_ProcPlaySound
   - 原理: 
    a. 跟 pipe 相同處: 可以在不相關的Process間傳遞資料, 同時通過發送和接收的方式傳遞資料
    b. name pipe: 發送資料: write(), 接收資料: read()
        Queue Message: 發送資料: msgsnd(), 接收資料: msgrcv()
    c. Message Queue 函數說明: 
       1. int msgget(key_t key, int msgflg): 創建 Message Queue或是獲取一個Message Queue
           SYS_QUEUE_Create()
            int msgflg = IPC_CREAT | 0666;
            static key_t key = 1000;
            msgget(key++, msgflg)
          (a). key: 多個Process可以通過key訪問同一個Message Queue
          疑問: 怎麼達成記錄不同的 Queue-ID, 收送可以認到相同的 Queue-ID 處理 Message ? 
          Ans: 1. static SYS_QUEUE_ID_T sip_core_queueId;
                  SYS_QUEUE_Create(, , sizeof(SIP_CORE_EVT_MSG_T), &sip_core_queueId)
                  Note: &sip_core_queueId
                  2. tatic key_t key = 1000;
                      msqid = msgget(key++, msgflg)
                      *queueId = msqid
  - Review static 變數 
    a. static 變數在函式呼叫之間儲存變數值
       - 將值保留在記憶體中的變數. 有一個靜態的儲存期限
    b. static 關鍵字來宣告檔案範圍內的變數
       - static 限定變數可以在任何函示外宣告, 使其在單個原始檔範圍內可見. 
         這樣的變數稱為具有內部聯絡的靜態變數, 也就是說它們的值只能被同一檔案中的函示使用
  2. int msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg)
     : 把 message送到已經創建(打開)的 Message Queue的尾端
     : msgid: Message Queue 標示符
     : msgp: 發送給Queue的Message.
  3. ssize_t msgrcv(int msgid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
     : 把Message Queue 從 Queue中取走, 跟 FIFO不同的是, 可以指定取走某一條Message
     : msgid: message queue 標示符
     : msgp:存放 message的結構體, 要與 msgsnd()發送的結構相同
  4. msgctl(): 可以完成多項功能
      - 實際使用: 刪除 msg 
         msgctl(queueId, IPC_RMID, NULL)
         > IPC_RMID 立即删除该 MSG,并且唤醒所有阻塞在该 MSG上的进程