Linux 程序間通訊 訊息佇列

2021-09-24 00:06:43 字數 3394 閱讀 5356

傳送訊息:

//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下進行程序間通訊的一種方法或機制匿名管道和命名管道,那麼這裡要說的是另外一種與之不同的通訊方法,即訊息佇列,兩者之間有相同也有不同的地方,具體的下面就一一介紹。一 什麼是訊息佇列?首先它也是一種進行程序間通訊的方式,通過乙個程序向另外乙個程序傳送資料塊的方式,每個資料...