傳送訊息:
//sender
#include #include typedef struct
msg_st;
int main()
接收訊息
//receiver
#include #include typedef struct
msg_st;
int main()
編譯並執行傳送端程式:
傳送訊息後,可通過ipcs命令檢視到訊息佇列:
執行接收程序,從佇列中接收乙個訊息:
再次使用ipcs,可以發現訊息佇列中messages為0,即佇列中沒有訊息了:
訊息佇列通過系統呼叫實現,如下圖所示:
每個訊息佇列以msg_queue為佇列頭,其中包含3個鍊錶:
(1)傳送者鍊錶。
(2)接受者鍊錶。
(3)訊息鍊錶。
msgget()函式的實現主體為ipcget_public(),函式呼叫關係如下:
syscall_define2(msgget) -> ipcget() -> ipcget_public()
static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
const struct ipc_ops *ops, struct ipc_params *params)
else
ipc_unlock(ipcp);
} up_write(&ids->rwsem);
return err;
}
msgsnd()函式主要功能由do_msgsnd()實現:
(1)先複製訊息型別,再複製訊息中的資料。
(2)傳送訊息的型別type必須大於0。
syscall_define4(msgsnd, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
int, msg***)
long do_msgsnd(int msqid, long mtype, void __user *mtext,
size_t msgsz, int msg***)
...} msq->q_lspid = task_tgid_vnr(current);
msq->q_stime = get_seconds();
if (!pipelined_send(msq, msg))
...}
msgrcv()函式的實現主體為do_msgrcv()。
其中,msgtpye取值不同,有不同的含義:
(1)等於0時,返回訊息佇列中的第乙個訊息。
(2)大於0時,返回訊息佇列中訊息佇列中訊息型別相等的第乙個訊息。
(3)小於0時,返回訊息佇列中小於-msgtype的所有訊息中,訊息型別最小的乙個訊息,例如訊息佇列中有3個訊息,訊息型別分別為1,3,5, 呼叫msgrcv函式時引數訊息型別的值為-4,則佇列中訊息型別為1的訊息被讀取。
syscall_define5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
long, msgtyp, int, msg***)
long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msg***,
long (*msg_handler)(void __user *, struct msg_msg *, size_t))
mode = convert_mode(&msgtyp, msg***);
rcu_read_lock();
msq = msq_obtain_object_check(ns, msqid);
if (is_err(msq))
for (;;)
/** if we are copying, then do not unlink message and do
* not update queue parameters.
*/if (msg*** & msg_copy)
list_del(&msg->m_list);
msq->q_qnum--;
msq->q_rtime = get_seconds();
msq->q_lrpid = task_tgid_vnr(current);
msq->q_cbytes -= msg->m_ts;
atomic_sub(msg->m_ts, &ns->msg_bytes);
atomic_dec(&ns->msg_hdrs);
ss_wakeup(&msq->q_senders, 0);
goto out_unlock0;
} /* no message waiting. wait for a message */
if (msg*** & ipc_nowait)
} bufsz = msg_handler(buf, msg, bufsz);
free_msg(msg);
return bufsz;
}
一旦從佇列中有匹配的訊息,則通過函式do_msg_fill()將訊息的內容從核心空間複製到使用者空間:
static long do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz)
通過msgctl可更改佇列的屬性,如佇列的最大位元組數,也可以刪除佇列。
syscall_define3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
}
Linux程序間通訊 訊息佇列
linux和類linux系統下程序間通訊 inter process communication,ipc 有很多種方式,包括套接字 socket 共享記憶體 shared memory 管道 pipe 訊息佇列 message queue 等,各自有各自的一些應用場景和用途,這次就來聊一聊訊息佇列這...
linux程序間通訊 訊息佇列
訊息佇列由id 唯一標識 訊息佇列就是乙個訊息的列表,使用者可在佇列中新增,讀取訊息等 可按照型別來收發訊息 int msgget key t key,int flag int msgsnd int msqid,const void msgp,size t size,int flag msqid 訊...
Linux程序間通訊 訊息佇列
首先上篇文章我們說到了linux下進行程序間通訊的一種方法或機制匿名管道和命名管道,那麼這裡要說的是另外一種與之不同的通訊方法,即訊息佇列,兩者之間有相同也有不同的地方,具體的下面就一一介紹。一 什麼是訊息佇列?首先它也是一種進行程序間通訊的方式,通過乙個程序向另外乙個程序傳送資料塊的方式,每個資料...