linux提權,linux消息隊列總結

 2023-10-31 阅读 28 评论 0

摘要:1.消息隊列簡介 實現linux進程通信的方式有5種: --信號(Singal) --管道(Pipe) linux提權,--消息隊列(Message) --信號量(Semaphore) 每種進程通信方式實現方式和功能不一樣,帶來適用的場景也有所不同

1.消息隊列簡介

實現linux進程通信的方式有5種:

--信號(Singal)

--管道(Pipe)

linux提權,--消息隊列(Message)

--信號量(Semaphore)

每種進程通信方式實現方式和功能不一樣,帶來適用的場景也有所不同,消息隊列是鏈表隊列,它通過內核提供一個struct msqid_ds *msgque[MSGMNI]向量維護內核的一個消息隊列列表,因此linux系統支持的最大消息隊列數由msgque數組大小來決定,每一個msqid_ds表示一個消息隊列,并通過msqid_ds.msg_first、msg_last維護一個先進先出的msg鏈表隊列,當發送一個消息到該消息隊列時,把發送的消息構造成一個msg結構對象,并添加到msqid_ds.msg_first、msg_last維護的鏈表隊列,同樣,接收消息的時候也是從msg鏈表隊列尾部查找到一個msg_type匹配的msg節點,從鏈表隊列中刪除該msg節點,并修改msqid_ds結構對象的數據。

2.消息隊列的數據結構

kafka消息隊列、--1.struct msqid_ds *msgque[MSGMNI]向量:

msgque[MSGMNI]是一個msqid_ds結構的指針數組,每個msqid_ds結構指針代表一個系統消息隊列,msgque[MSGMNI]的大小為MSGMNI=128,也就是說系統最多有MSGMNI=128個消息隊列

--2.struct msqid_ds

一個消息隊列結構

struct msqid_ds 中主要數據成員介紹如下:

redis消息隊列原理。struct msqid_ds

{

struct ipc_perm msg_perm;

struct msg *msg_first; /*消息隊列頭指針*/

struct msg *msg_last; /*消息隊列尾指針*/

Redis消息隊列, __kernel_time_t msg_stime; /*最后一次插入消息隊列消息的時間*/

__kernel_time_t msg_rtime; /*最后一次接收消息即刪除隊列中一個消息的時間*/

__kernel_time_t msg_ctime;

struct wait_queue *wwait; /*發送消息等待進程隊列*/

struct wait_queue *rwait;

多線程消息隊列、 unsigned short msg_cbytes;

unsigned short msg_qnum; /*消息隊列中的消息個數*/

unsigned short msg_qbytes;

__kernel_ipc_pid_t msg_lspid; /*最后一次消息發送進程的pid*/

__kernel_ipc_pid_t msg_lrpid; /*最后一次消息發送進程的pid*/

linux有什么用?};

--3.struct msg 消息節點結構:

msqid_ds.msg_first,msg_last維護的鏈表隊列中的一個鏈表節點

struct msg

{

linux、msg *msg_next; /*下一個msg*/

long msg_type; /*消息類型*/

*msg_spot; /*消息體開始位置指針*/

msg_ts; /*消息體長度*/

message; /*消息體*/

linux實驗總結?}

--4.msgbuf消息內容結構:

msg 消息節點中的消息體,也是消息隊列使用進程(消息隊列發送接收進程)發送或者接收的消息

struct msgbuf

{

linux消息隊列自動銷毀? long mtype; --消息類型

char mtext[n];--消息內容

}

3.消息隊列的使用

--1.消息隊列Key的獲取:

redis消息隊列實現思路、 在程序中若要使用消息隊列,必須要能知道消息隊列key,因為應用進程無法直接訪問內核消息隊列中的數據結構,因此需要一個消息隊列的標識,讓應用進程知道當前操作的是哪個消息隊列,同時也要保證每個消息隊列key值的唯一性

----a.通過ftok函數獲取

key_t key;

key=ftok(".","a")

該函數通過一個路徑名稱映射出一個消息隊列key(我的理解是使用路徑映射的方式比較容易獲取一個唯一的消息隊列key)

關于linux基礎的個人總結、----b.直接定義key:

#define MSG_KEY 123456

自定義key的方式要注意避免消息隊列的重復。

--2.獲取或者打開一個消息隊列

----a.使用說明

redis消息隊列實現高并發、qid=msgget(key_t key, int msgflag)

--key: 消息隊列key

--msgflag:

IPC_PRIVATE:創建一個該進程獨占的消息隊列,其它進程不能訪問該消息隊列

IPC_CREAT:若消息隊列不存在,創建一個新的消息隊列,若消息隊列存在,返回存在的消息隊列

java 消息隊列、IPC_CREAT | IPC_EXCL: IPC_EXCL標志本身沒有多大意義,與IPC_CREAT一起使用,保證只創建新的消息隊列,若對應key的消息隊列已經存在,則返回錯誤

IPC_NOWAIT:小隊列以非阻塞的方式獲取(若不能獲取,立即返回錯誤)

----b.函數原因

------1)如果key==IPC_PRIVATE,則申請一塊內存,創建一個新的消息隊列(數據結構msqid_ds),將其初始化后加入到msgque向量表中的某個空位置處,返回標示符。

------2)在msgque向量表中找鍵值為key的消息隊列,如果沒有找到,結果有二:

msgflag表示不創建新的隊列,則錯誤返回。

msgflag表示要創建新的隊列(IPC_CREAT),則創建新消息隊列,創建過程如1)。

-------3)如果在msgque向量表中找到了鍵值為key的消息隊列,則有以下情況:

如果msgflg表示一定要創建新的消息隊列而且不允許有相同鍵值的隊列存在,則錯誤返回。

如果找到的隊列是不能用的或已經損壞的隊列,則錯誤返回。

認證和存取權限檢查,如果該隊列不允許msgflg要求的存取,則錯誤返回。

正常,返回隊列的標識符。

--3.發送一個消息到消息對列

----a.使用說明:

int msgsnd (int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg)
------msqid為消息隊列的qid
------msgp對應消息內容結構體指針
------msgsz消息的大小即msgp指針指向的消息結構體的大小
------msgflg消息標志

0:忽略該標志位,以阻塞的方式發送消息到消息隊列

IPC_NOWAIT:以非阻塞的方式發送消息,若消息隊列滿,函數立即返回。

------返回:

0: 成功

-1:非阻塞方式訪問滿消息隊列返回

EACCES:沒有該消息隊列寫權限

EFAULT:消息隊列地址無法獲取

EIDRM:消息隊列已經被刪除

EINTR:消息隊列等待寫入的時候被中斷

ENOMEM:內存不夠

----b.函數原理:

1)計算id = (unsigned int) msqid % MSGMNI,然后根據id在linux系統消息隊列向量msgque[MSGMNI]中查找對應的消息隊列,并進行認證檢查,合法性檢查

2)如果隊列已滿,以可中斷等待狀態(TASK_INTERRUPTIBLE)將當前進程掛起在wwait等待隊列(發送消息等待隊列)上(msgflag==0)。

3)否則 根據msgbuf的大小申請一塊空間,并在其上創建一個消息數據結構struct msg(內核空間),將消息緩沖區中的消息內容拷貝到該內存塊中消息頭的后面(從用戶空間拷貝到內核空間)。

4)將消息數據結構加入到消息隊列的隊尾,修改隊列msqid_ds的相應參數。

5)喚醒在該消息隊列的rwait進程隊列(讀等待進程隊列)上等待讀的進程,并返回。

--4.從消息隊列接收一個消息到msgbuf*

----a.使用說明
int msgrcv (int msqid, struct msgbuf *msgp, size_t msgsz,long msgtyp, int msgflg)
----msqid為消息隊列的qid
----msgp是接收到的消息將要存放的緩沖區
----msgsz是消息的大小
----msgtyp是期望接收的消息類型
----msgflg是標志

0:表示忽略

IPC_NOWAIT:如果消息隊列為空,不阻塞等待,返回一個ENOMSG

----返回

0:成功

-1:消息長度大于msgsz

EACCES:沒有該消息隊列讀權限

EFAULT:消息隊列地址無法獲取

EIDRM:消息隊列已經被刪除

EINTR:消息隊列等待寫入的時候被中斷

ENOMEM:內存不夠

----b.函數原理:

1)計算id = (unsigned int) msqid % MSGMNI,然后根據id在msgque[MSGMNI]中查找對應的消息隊列,并進行認證檢查,合法性檢查
2)根據msgtyp搜索消息隊列,情況有二:
----如果找不到所要的消息,則以可中斷等待狀態(TASK_INTERRUPTIBLE)將當前進程掛起在rwait等待隊列上
----如果找到所要的消息,則將消息從隊列中摘下,調整隊列msqid_ds參數,喚醒該消息隊列的wwait進程隊列上等待寫的進程,將消息內容拷貝到用戶空間的消息緩沖區msgp中,釋放內核中該消息所占用的空間,返回

--5.消息的控制

----a.使用說明:

int msgctl (int msqid, int cmd, struct msqid_ds *buf)

------msqid:為消息隊列的qid
------cmd:為該函數要對消息隊列執行的操作

IPC_STAT:取出消息隊列的msqid_ds結構體并將參數存入buf所指向的msqid_ds結構對象中

IPC_SET:設定消息隊列的msqid_ds 數據中的msg_perm 成員。設定的值由buf 指向的msqid_ds
結構給出。

IPC_EMID:將隊列從系統內核中刪除。
----buf:消息隊列msqid_ds結構體指針

----b.函數作用

對消息隊列進行設置以及相關操作,具體操作由cmd指定。

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/3/165460.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息