国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Linux進程間通信【消息隊列、信號量】

這篇具有很好參考價值的文章主要介紹了Linux進程間通信【消息隊列、信號量】。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

?個人主頁: 北 海
??所屬專欄: Linux學習之旅
??操作環(huán)境: CentOS 7.6 阿里云遠程服務器

Linux進程間通信【消息隊列、信號量】



??前言

System V 通信標準中,還有一種通信方式:消息隊列,以及一種實現(xiàn)互斥的工具:信號量;隨著時代的發(fā)展,這些陳舊的標準都已經(jīng)較少使用了,但作為 IPC 中的經(jīng)典知識,我們可以對其做一個簡單了解,擴展 IPC 的知識棧,尤其是 信號量,可以通過它,為以后多線程學習中 POSIX 信號量的學習做鋪墊

Linux進程間通信【消息隊列、信號量】


???正文

1、消息隊列

1.1、什么是消息隊列?

消息隊列(Message Queuing)是一種比較特殊的通信方式,它不同于管道與共享內(nèi)存那樣借助一塊空間進行數(shù)據(jù)讀寫,而是 在系統(tǒng)中創(chuàng)建了一個隊列,這個隊列的節(jié)點就是數(shù)據(jù)塊,包含類型和信息

  • 假設(shè)現(xiàn)在進程 A、B 想要通過消息隊列進行通信,首先創(chuàng)建一個消息隊列
  • 然后進程 A 將自己想要發(fā)送給進程 B 的信息打包成數(shù)據(jù)塊(其中包括發(fā)送方的信息),將數(shù)據(jù)塊添加至消息隊列隊尾處
  • 進程 B 同樣也可以向消息隊列中添加數(shù)據(jù)塊,同時也會從消息隊列中捕獲其他進程的數(shù)據(jù)塊,解析后進行讀取,這樣就完成了通信

Linux進程間通信【消息隊列、信號量】
遍歷消息隊列時,存數(shù)據(jù)塊 還是 取數(shù)據(jù)塊 取決于 數(shù)據(jù)塊中的類型 type

注意:消息隊列跟共享內(nèi)存一樣,是由操作系統(tǒng)創(chuàng)建的,其生命周期不隨進程,因此在使用結(jié)束后需要刪除

因為消息隊列比陳舊且較少使用了,所以這里就不詳細講解原理,關(guān)于消息隊列更詳細的介紹可以看看這兩篇文章:

  • 《什么是消息隊列》
  • 《消息隊列詳解》

1.2、消息隊列的數(shù)據(jù)結(jié)構(gòu)

同屬于 System V 標準,消息隊列也有屬于自己的數(shù)據(jù)結(jié)構(gòu)

注:msg 表示 消息隊列

struct msqid_ds
{
	struct ipc_perm msg_perm;	/* Ownership and permissions */
	time_t msg_stime;			/* Time of last msgsnd(2) */
	time_t msg_rtime;			/* Time of last msgrcv(2) */
	time_t msg_ctime;			/* Time of last change */
	unsigned long __msg_cbytes; /* Current number of bytes in queue (nonstandard) */
	msgqnum_t msg_qnum;			/* Current number of messages in queue */
	msglen_t msg_qbytes;		/* Maximum number of bytes allowed in queue */
	pid_t msg_lspid;			/* PID of last msgsnd(2) */
	pid_t msg_lrpid;			/* PID of last msgrcv(2) */
};

共享內(nèi)存 一樣,其中 struct ipc_perm 中存儲了 消息隊列的基本信息,具體包含內(nèi)容如下:

struct ipc_perm
{
	key_t __key;		  /* Key supplied to msgget(2) */
	uid_t uid;			  /* Effective UID of owner */
	gid_t gid;			  /* Effective GID of owner */
	uid_t cuid;			  /* Effective UID of creator */
	gid_t cgid;			  /* Effective GID of creator */
	unsigned short mode;  /* Permissions */
	unsigned short __seq; /* Sequence number */
};

可以通過 man msgctl 查看函數(shù)使用手冊,其中就包含了 消息隊列 的數(shù)據(jù)結(jié)構(gòu)信息

1.3、消息隊列的相關(guān)接口

論標準的重要性,消息隊列的大小接口風格與共享內(nèi)存一致,都是出自 System V 標準

1.3.1、創(chuàng)建

使用 msgget 函數(shù)創(chuàng)建 消息隊列

Linux進程間通信【消息隊列、信號量】

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgget(key_t key, int msgflg);

關(guān)于 msgget 函數(shù)

組成部分 含義
返回值 int 創(chuàng)建成功返回消息隊列的 msqid,失敗返回 -1
參數(shù)1 key_t key 創(chuàng)建共享內(nèi)存時的唯一 key 值,通過函數(shù)計算獲取
參數(shù)2 int msgflg 位圖,可以設(shè)置消息隊列的創(chuàng)建方式及創(chuàng)建權(quán)限

共享內(nèi)存shmget 可以說是十分相似了,關(guān)于 ftok 函數(shù)計算 key 值,這里就不再闡述,可以在這篇文章中學習 《Linux進程間通信【共享內(nèi)存】》

簡單使用函數(shù) msgget 創(chuàng)建 消息隊列,并使用 ipcs -q 指令查看資源情況

#include <iostream>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

using namespace std;

int main()
{
    //創(chuàng)建消息隊列
    int n = msgget(ftok("./", 668), IPC_CREAT | IPC_EXCL | 0666);
    if(n == -1)
    {
        cerr << "msgget fail!" << endl;
        exit(1);
    }
    return 0;
}

Linux進程間通信【消息隊列、信號量】

程序運行后,創(chuàng)建出了一個 msqid0 的消息隊列

因為此時并 沒有使用消息隊列進行通信,所以已使用字節(jié) used-bytes 和 消息數(shù) messages 都是 0

注意:

  • 消息隊列在創(chuàng)建時,也需要指定創(chuàng)建方式:IPC_CREAT、IPC_EXCL、權(quán)限 等信息
  • 消息隊列創(chuàng)建后,msqid也是隨機生成的,大概率每次都不一樣
  • 消息隊列生命周期也是隨操作系統(tǒng)的,并不會因進程的結(jié)束而釋放
1.3.2、釋放

消息隊列也有兩種釋放方式:通過指令釋放、通過函數(shù)釋放

釋放指令:ipcrm -q msqid 釋放消息隊列,其他 System V 通信資源也可以這樣釋放

  • ipcrm -m shmid 釋放共享內(nèi)存
  • ipcrm -s semid 釋放信號量集

Linux進程間通信【消息隊列、信號量】

釋放函數(shù):msgctl(msqid, IPC_RMID, NULL) 釋放指定的消息隊列,跟 shmctl 刪除共享內(nèi)存一樣

Linux進程間通信【消息隊列、信號量】

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

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

關(guān)于 msgctl 函數(shù)

組成部分 含義
返回值 int 成功返回 0,失敗返回 -1
參數(shù)1 int msqid 待控制的消息隊列 id
參數(shù)2 int cmd 控制消息隊列的具體動作,同樣是位圖
參數(shù)3 struct msqid_ds *buf 用于獲取或設(shè)置所控制消息隊列的數(shù)據(jù)結(jié)構(gòu)

簡單回顧下參數(shù)2部分可傳遞參數(shù):

  • IPC_RMID 表示刪除共享內(nèi)存
  • IPC_STAT 用于獲取或設(shè)置所控制共享內(nèi)存的數(shù)據(jù)結(jié)構(gòu)
  • IPC_SET 在進程有足夠權(quán)限的前提下,將共享內(nèi)存的當前關(guān)聯(lián)值設(shè)置為 buf 數(shù)據(jù)結(jié)構(gòu)中的值

同樣的,消息隊列 = 消息隊列的內(nèi)核數(shù)據(jù)結(jié)構(gòu)(struct msqid_ds) + 真正開辟的空間

1.3.3、發(fā)送

利用消息隊列發(fā)送信息,即 將信息打包成數(shù)據(jù)塊,入隊尾,所使用函數(shù)為 msgsnd

Linux進程間通信【消息隊列、信號量】

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

關(guān)于 msgsnd 函數(shù)

組成部分 含義
返回值 int 成功返回 0,失敗返回 -1
參數(shù)1 int msqid 待發(fā)送數(shù)據(jù)塊的消息隊列 id
參數(shù)2 const void *msgp 待發(fā)送的數(shù)據(jù)塊
參數(shù)3 size_t msgsz 待發(fā)送數(shù)據(jù)塊大小
參數(shù)4 int msgflg 表示發(fā)送數(shù)據(jù)塊的方式,一般默認為 0

參數(shù)2 表示待發(fā)送的數(shù)據(jù)塊,這顯然是一個結(jié)構(gòu)體類型,需要自己定義,結(jié)構(gòu)如下:

struct msgbuf
{
    long mtype;    /* message type, must be > 0 */
    char mtext[1]; /* message data */
};

mtype 就是傳說中數(shù)據(jù)塊類型,據(jù)發(fā)送方而設(shè)定;mtex 是一個比較特殊的東西:柔性數(shù)組,其中存儲待發(fā)送的 信息,因為是 柔性數(shù)組,所以可以根據(jù) 信息 的大小靈活調(diào)整數(shù)組的大小

關(guān)于 柔性數(shù)組 的詳細介紹可以看看這篇文章 《C語言進階——動態(tài)內(nèi)存管理

1.3.4、接收

消息發(fā)送后,總得接收吧,既然發(fā)送是往隊尾中添加數(shù)據(jù)塊,那么接收就是 從隊頭中取數(shù)據(jù)塊,假設(shè)所取數(shù)據(jù)塊為自己發(fā)送的,那么就不進行操作,其他情況則取出數(shù)據(jù)塊,使用 msgrcv 函數(shù)接收信息

Linux進程間通信【消息隊列、信號量】

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

關(guān)于 msgrcv 函數(shù)

組成部分 含義
返回值 int 成功返回實際從 mtext 數(shù)組中讀取的字節(jié)數(shù),失敗返回 -1
參數(shù)1 int msqid 待接收數(shù)據(jù)塊的消息隊列 id
參數(shù)2 void *msgp 接收到的數(shù)據(jù)塊,是一個輸出型參數(shù)
參數(shù)3 size_t msgsz 要接收數(shù)據(jù)塊的大小
參數(shù)4 long msgtyp 要接收數(shù)據(jù)塊的類型
參數(shù)5 int msgflg 表示接收數(shù)據(jù)塊的方式,一般默認為 0

同樣的,接收的數(shù)據(jù)結(jié)構(gòu)如下所示,也包含了 類型柔性數(shù)組

struct msgbuf
{
    long mtype;    /* message type, must be > 0 */
    char mtext[1]; /* message data */
};

1.4、消息隊列小結(jié)

消息隊列 的大部分接口都與 共享內(nèi)存 近似,所以掌握 共享內(nèi)存 后,即可快速上手 消息隊列

但是如你所見,System V 版的 消息隊列 使用起來比較麻煩,并且過于陳舊,現(xiàn)在已經(jīng)較少使用了,所以我們不必對其進行深究,知道個大概就行了,如果實際中真遇到了,再查文檔也不遲


2、信號量

2.1、什么是信號量?

信號量(semaphore)一種特殊的工具,主要用于實現(xiàn) 同步和互斥

信號量 又稱 信號燈,是各大高校《操作系統(tǒng)》課程中老師提及的高頻知識點,往往伴隨著 P、V 操作出現(xiàn),但大多數(shù)老師都只是提及了基本概念,并未對 信號量 的本質(zhì)及使用場景作出詳細講解

在正式學習 信號量 相關(guān)知識前,需要先簡單了解下 互斥相關(guān)四個概念,為后續(xù) 多線程中信號量的學習作鋪墊(重點)

2.2、互斥相關(guān)概念

1、并發(fā) 是指系統(tǒng)中同時存在多個獨立的活動單元

  • 比如在多線程中,多個執(zhí)行流可以同時執(zhí)行代碼,可能訪問同一份共享資源

2、互斥 是指同一時刻只允許一個活動單元使用共享資源

  • 即在任何一個時刻,都只允許一個執(zhí)行流進行共享資源的訪問(可以通過加鎖實現(xiàn))

3、臨界資源臨界區(qū),多執(zhí)行流環(huán)境中的共享資源就是 臨界資源,涉及 臨界資源 操作的代碼區(qū)間即 臨界區(qū)

  • 在多線程環(huán)境中,全局變量就是 臨界資源,對全局變量的修改、訪問代碼屬于 臨界區(qū)

4、原子性:只允許存在 成功 和 失敗 兩種狀態(tài)

  • 比如對變量的修改,要么修改成功,要么修改失敗,不會存在修改一半被切走的狀態(tài)

所以 互斥 是為了解決 臨界資源 在多執(zhí)行流環(huán)境中的并發(fā)訪問問題,需要借助 互斥鎖 或 信號量 等工具實現(xiàn) 原子操作,實現(xiàn) 互斥

Linux進程間通信【消息隊列、信號量】

關(guān)于互斥鎖(mutex) 的相關(guān)知識在 多線程 中介紹,現(xiàn)在先來學習 信號量,搞清楚它是如何實現(xiàn) 互斥

2.3、信號量的感性理解

將整個程序看作現(xiàn)實世界,形色各異的人看作 執(zhí)行流,電影院 等公共資源看作 臨界區(qū),而單場電影的電影票看作 臨界資源,主角 信號量 就是電影院中單場電影余票的 計數(shù)器,即余票越多,計數(shù)器值越大,當有人買票時,計數(shù)器 -1,當有人看完電影時,計數(shù)器 +1

當電影票賣完時,計數(shù)器歸零,其他想看電影的人也無法購票觀看本場電影

下面這些情況應運而生:

  1. 當你購票成功后,計數(shù)器 -1,你必然可以去看這場電影,其他人也無法與你爭奪,因為那個位置當電影放映之時就是屬于你一個人的
  2. 如果你買票晚了,票已告罄,計數(shù)器為 0,你就無法購票觀看這場電影,即使自己偷偷溜進去也不行,會被保安叉出去,這是規(guī)定
  3. 得益于計數(shù)器的控制,電影院在放映電影時,有效劃分了電影票這個 臨界資源 的所屬權(quán)限,從而保證了在電影放映時,絕對不會發(fā)生位置沖突、位置爆滿、非法闖入等各種情況

Linux進程間通信【消息隊列、信號量】

信號量 的設(shè)計初衷也是如此,就是為了避免 因多執(zhí)行流對臨界資源的并發(fā)訪問,而導致程序運行出現(xiàn)問題

因為電影院一次能容納幾十個人,所以可能不太好理解 互斥 這個概念,將場景特殊化,現(xiàn)在有一個 頂級VIP放映室,每天飲料零食隨便吃,但 一次只允許一個人看電影,與普通電影院一樣,這個 頂級VIP放映室 也有自己的售票系統(tǒng),其本質(zhì)同樣是 計數(shù)器,但此時 計數(shù)器初始值為 1

所以:當一群人都想進這個頂級VIP放映室看電影時,必須等到 計數(shù)器 為 1 時,才能進行搶票,才有資格進去看電影,當然一次只能放一個人進去,同時計數(shù)器是否恢復 1,取決于上一個看電影的人是否出了放映室 -> 看電影結(jié)束 -> 計數(shù)器 +1

規(guī)定:只允許一個人看電影

Linux進程間通信【消息隊列、信號量】

透過現(xiàn)象看本質(zhì),在 頂級VIP看電影 不就是代碼中 多個執(zhí)行流對同一個臨界資源的互斥訪問嗎? 此時的 信號量 可以設(shè)為 1,確保 只允許一個執(zhí)行流進行訪問,這種 信號量 被稱為 二元信號量,常用來實現(xiàn) 互斥

綜上所述,信號量本質(zhì)上就是 計數(shù)器 count,所謂的 P 操作(申請)就是在對 count--,V 操作(歸還)則是在對 count++

2.4、信號量的數(shù)據(jù)結(jié)構(gòu)

下面來看看 信號量 的數(shù)據(jù)結(jié)構(gòu),通過 man semctl 進行查看

注:sem 表示 信號量

struct semid_ds
{
    struct ipc_perm sem_perm; /* Ownership and permissions */
    time_t sem_otime;         /* Last semop time */
    time_t sem_ctime;         /* Last change time */
    unsigned long sem_nsems;  /* No. of semaphores in set */
};

System V 家族基本規(guī)矩,struct ipc_perm 中存儲了 信號量的基本信息,具體包含內(nèi)容如下:

struct ipc_perm
{
    key_t __key;          /* Key supplied to semget(2) */
    uid_t uid;            /* Effective UID of owner */
    gid_t gid;            /* Effective GID of owner */
    uid_t cuid;           /* Effective UID of creator */
    gid_t cgid;           /* Effective GID of creator */
    unsigned short mode;  /* Permissions */
    unsigned short __seq; /* Sequence number */
};

顯然,無論是 共享內(nèi)存、消息隊列、信號量,它們的 ipc_perm 結(jié)構(gòu)體中的內(nèi)容都是一模一樣的,結(jié)構(gòu)上的統(tǒng)一可以帶來管理上的便利,具體原因可以接著往下看

2.5、信號量的相關(guān)接口

2.5.1、創(chuàng)建

信號量的申請比較特殊,一次可以申請多個信息量,官方稱此為 信號量集,所使用函數(shù)為 semget

Linux進程間通信【消息隊列、信號量】

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

int semget(key_t key, int nsems, int semflg);

關(guān)于 semget 函數(shù)

組成部分 含義
返回值 int 創(chuàng)建成功返回信號量集的 semid,失敗返回 -1
參數(shù)1 key_t key 創(chuàng)建信號量集時的唯一 key 值,通過函數(shù) ftok 計算獲取
參數(shù)2 int nsems 待創(chuàng)建的信號量個數(shù),這也正是 集 的來源
參數(shù)3 int semflg 位圖,可以設(shè)置消息隊列的創(chuàng)建方式及創(chuàng)建權(quán)限

除了參數(shù)2,其他基本與另外倆兄弟一模一樣,實際傳遞時,一般傳 1,表示只創(chuàng)建一個 信號量

使用函數(shù)創(chuàng)建 信號量集,并通過指令 ipcs -s 查看創(chuàng)建的 信號量集 信息

#include <iostream>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

using namespace std;

int main()
{
    //創(chuàng)建一個信號量
    int n = semget(ftok("./", 668), 1, IPC_CREAT | IPC_EXCL | 0666);
    if(n == -1)
    {
        cerr << "semget fail!" << endl;
        exit(1);
    }
    return 0;
}

Linux進程間通信【消息隊列、信號量】

程序運行后,創(chuàng)建了一個 信號量集,nsems1,表示在當前 信號量集 中只有一個 信號量

注意:

  • 信號量集在創(chuàng)建時,也需要指定創(chuàng)建方式:IPC_CREATIPC_EXCL、權(quán)限 等信息
  • 信號量集創(chuàng)建后,semid也是隨機生成的,大概率每次都不一樣
  • 信號量集生命周期也是隨操作系統(tǒng)的,并不會因進程的結(jié)束而釋放
2.5.2、釋放

老生常談的兩種釋放方式:指令釋放、函數(shù)釋放

指令釋放:直接通過指令 ipcrm -s semid 釋放信號量集

Linux進程間通信【消息隊列、信號量】

通過函數(shù)釋放:semctl(semid, semnum, IPC_RMID),信號量中的控制函數(shù)有一點不一樣

Linux進程間通信【消息隊列、信號量】

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

int semctl(int semid, int semnum, int cmd, ...);

關(guān)于 semctl 函數(shù)

組成部分 含義
返回值 int 成功返回 0,失敗返回 -1
參數(shù)1 int semid 待控制的信號量集 id
參數(shù)2 int semnum 表示對信號量集中的第 semnum 個信號量作操作
參數(shù)3 int cmd 控制信號量的具體動作,同樣是位圖
參數(shù)4 ... 可變參數(shù)列表,不止可以獲取信號量的數(shù)據(jù)結(jié)構(gòu),還可以獲取其他信息

注意:

  • 參數(shù)2 表示信號量集中的某個信號量編號,從 1 開始編號
  • 參數(shù)3 中可傳遞的動作與共享內(nèi)存、消息隊列一致
  • 參數(shù)4 就像 printfscanf 中最后一個參數(shù)一樣,可以靈活使用
2.5.3、操作

信號量的操縱比較ex,也比較麻煩,所以僅作了解即可

使用 semop 函數(shù)對 信號量 進行諸如 +1、-1 的基本操作

Linux進程間通信【消息隊列、信號量】

 #include <sys/types.h>
 #include <sys/ipc.h>
 #include <sys/sem.h>

 int semop(int semid, struct sembuf *sops, unsigned nsops);

關(guān)于 semop 函數(shù)

組成部分 含義
返回值 int 成功返回 0,失敗返回 -1
參數(shù)1 int semid 待操作的信號量集 id
參數(shù)2 struct sembuf *sops 一個比較特殊的參數(shù),需要自己設(shè)計結(jié)構(gòu)體
參數(shù)3 unsigned nsops 可以簡單理解為信號量編號

重點在于參數(shù)2,這是一個結(jié)構(gòu)體,具體成員如下:

unsigned short sem_num;  /* semaphore number */
short          sem_op;   /* semaphore operation */
short          sem_flg;  /* operation flags */

其中包含信號量編號、操作等信息,需要我們自己設(shè)計出一個結(jié)構(gòu)體,然后傳給 semop 函數(shù)使用

可以簡單理解為:sem_op 就是要進行的操作,如果將 sem_op 設(shè)為 -1,表示信號量 -1(申請),同理 +1 表示信號量 +1(歸還)

sem_flg 是設(shè)置動作,一般設(shè)為默認即可

當然這些函數(shù)我們不必深入去研究,知道個大概就行了

2.6、信號量小結(jié)

信號量 是實現(xiàn) 互斥 的其中一種方法,具體表現(xiàn)為:資源申請,計數(shù)器 -1,資源歸還,計數(shù)器 +1,只有在計數(shù)器不為 0 的情況下,才能進行資源申請,可以設(shè)計 二元信號量 實現(xiàn) 互斥

System V 中的 信號量 操作比較麻煩,但 信號量 的思想還是值得一學的,等后面學習 多線程 時,也會使用 POSIX 中的 信號量 實現(xiàn) 互斥,相比之下,POSIX 版的信號量操作要簡單得多,同時應用也更為廣泛

因為 信號量 需要被多個獨立進程看到,所以 信號量 本身也是 臨界資源,不過它是 原子 的,所以可以用于 互斥

  • 多個獨立進程看到同一份資源,這就是 IPC 的目標,所以 信號量 被劃分至進程間通信中

3、深入理解 System V 通信方式

不難發(fā)現(xiàn),共享內(nèi)存、消息隊列、信號量的數(shù)據(jù)結(jié)構(gòu)基本一致,并且都有同一個成員 struct ipc_perm,所以實際對于 操作系統(tǒng) 來說,對 System V 中各種方式的描述管理只需要這樣做:

  • 將 共享內(nèi)存、消息隊列、信號量對象描述后,統(tǒng)一存入數(shù)組中
  • 再進行指定對象創(chuàng)建時,只需要根據(jù) ipc_id_arr[n]->__key 進行比對,即可當前對象是否被創(chuàng)建!
  • 因為 struct shmid_dsstruct ipc_perm shm_perm 的地址一致(其他對象也一樣),所以可以對當前位置的指針進行強轉(zhuǎn):((struct shmid_ds)ipc_id_arr[0]) 即可訪問 shmid_ds 中的成員,這不就是多態(tài)中的虛表嗎?

這樣一來,操作系統(tǒng)可以只根據(jù)一個地址,靈活訪問 兩個結(jié)構(gòu)體中的內(nèi)容,比如 struct ipc_perm shm_permstruct shmid_ds,并且操作系統(tǒng)還把多種不同的對象,描述融合入了一個 ipc_id_arr 指針數(shù)組中,真正做到了 高效管理

注:默認 ipc_id_arr[n] 訪問的是 struct ipc_perm 中的成員

Linux進程間通信【消息隊列、信號量】

注:上述圖示只是一個草圖,目的是為了輔助理解原理,并非操作系統(tǒng)中真實樣貌

操作系統(tǒng)在進行比較判斷時,如何判斷類型呢?

  • 這就是操作系統(tǒng)設(shè)計的巧妙之處了,ipc_id_arr 沒那么簡單,它會存儲對象的相應類型信息

通過下標(id) 訪問對象,這與文件系統(tǒng)中的機制不謀而合,不過實現(xiàn)上略有差異,間接導致 System V 的管理系統(tǒng)被邊緣化(歷史選擇了文件系統(tǒng))

shmid、msqidsemid 都是 ipc_id_arr 的下標,為什么值很大呢?

  • 在進行查找時,會將這些 id % 數(shù)組大小 進行轉(zhuǎn)換,確保不會發(fā)生越界,事實上,這個值與開機時間有關(guān),開機越長,值越大,當然到了一定程度后,會重新輪回

將內(nèi)核中的所有 ipc 資源統(tǒng)一以數(shù)組的方式進行管理

  • 假設(shè)想訪問具體 ipc 中的資源,可以通過 ipc_id_arr[n] 強轉(zhuǎn)為對應類型指針,再通過 -> 訪問其中的其他資源

以上方法就是 多態(tài),通過父類指針,訪問成員


??總結(jié)

以上就是本次關(guān)于 Linux 進程間通信【消息隊列、信號量】的全部內(nèi)容了,消息隊列和信號量相對來說不怎么重要,因此本文主要以理論為主,并未涉及很多實操代碼;本文中最重要的內(nèi)容莫過于理解 互斥 相關(guān)概念與 信號量 實現(xiàn)互斥的原理,最后關(guān)于操作系統(tǒng)對 System V 通信相關(guān)資源的封裝也算得上是精彩絕倫


Linux進程間通信【消息隊列、信號量】

文章來源地址http://www.zghlxwxcb.cn/news/detail-478644.html

相關(guān)文章推薦

Linux進程間通信【共享內(nèi)存】

Linux進程間通信【命名管道】

Linux進程間通信【匿名管道】

Linux基礎(chǔ)IO【軟硬鏈接與動靜態(tài)庫】

Linux基礎(chǔ)IO【深入理解文件系統(tǒng)】

Linux【模擬實現(xiàn)C語言文件流】

Linux基礎(chǔ)IO【重定向及緩沖區(qū)理解】

到了這里,關(guān)于Linux進程間通信【消息隊列、信號量】的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務器費用

相關(guān)文章

  • 【linux】進行間通信——共享內(nèi)存+消息隊列+信號量

    【linux】進行間通信——共享內(nèi)存+消息隊列+信號量

    進程間通信方式目前我們已經(jīng)學了匿名管道,命名管道。讓兩個獨立的進程通信,前提是看到同一份資源。匿名管道適用于血緣關(guān)系的進程,一個打開寫端一個打開讀端實現(xiàn)的。命名管道適用于完全獨立的進程,打開同一份文件實現(xiàn)的。 接下來我們看看剩下的實現(xiàn)進程間通信

    2024年02月05日
    瀏覽(22)
  • linux進程間通信(信號量)

    linux進程間通信(信號量)

    信號量是一個特殊的變量,程序?qū)ζ湓L問都是原子操作,且只允許對它進行等待(即 P(信號變量))和發(fā) 送(即 V(信號變量))信息操作。最簡單的信號量是只能取 0 和 1 的變量,這也是信號量最常見的一種形式, 叫做二進制信號量。而可以取多個正整數(shù)的信號量被稱為通用信號

    2024年02月07日
    瀏覽(33)
  • 【Linux】進程間通信 -- 信號量

    【Linux】進程間通信 -- 信號量

    信號量是什么? 本質(zhì)是一個計數(shù)器,通常用來表示公共資源中,資源數(shù)量多少的問題 公共資源:能被多個進程同時可以訪問的資源 訪問沒有保護的公共資源:數(shù)據(jù)不一致問題(比如我想寫abc123,但是我123還沒有寫入,就讀取了abc,可能數(shù)據(jù)分開會導致數(shù)據(jù)無意義) 為什么要

    2024年02月16日
    瀏覽(25)
  • 【Linux】System V 共享內(nèi)存、消息隊列、信號量

    【Linux】System V 共享內(nèi)存、消息隊列、信號量

    ?? 作者: 阿潤菜菜 ?? 專欄: Linux系統(tǒng)編程 System V 共享內(nèi)存是一種進程間通信的機制,它允許多個進程 共享一塊物理內(nèi)存區(qū)域 (稱為“段”)。System V 共享內(nèi)存的優(yōu)點是效率高,因為進程之間不需要復制數(shù)據(jù);缺點是 需要進程之間進行同步,以避免數(shù)據(jù)的不一致性 。 共

    2024年02月04日
    瀏覽(22)
  • 【Linux】進程間通信——System V信號量

    【Linux】進程間通信——System V信號量

    目錄 寫在前面的話 一些概念的理解 信號量的引入 信號量的概念及使用 ? ???????? System V信號量是一種較低級的IPC機制 ,使用的時候需要手動進行操作和同步。在現(xiàn)代操作系統(tǒng)中,更常用的是 POSIX信號量 (通過 sem_* 系列的函數(shù)進行操作)或更高級的同步原語(如互斥鎖

    2024年02月11日
    瀏覽(21)
  • linux中互斥鎖,自旋鎖,條件變量,信號量,與freeRTOS中的消息隊列,信號量,互斥量,事件的區(qū)別

    linux中互斥鎖,自旋鎖,條件變量,信號量,與freeRTOS中的消息隊列,信號量,互斥量,事件的區(qū)別

    對于目前主流的RTOS的任務,大部分都屬于并發(fā)的線程。 因為MCU上的資源每個任務都是共享的,可以認為是單進程多線程模型。 【freertos】003-任務基礎(chǔ)知識 在沒有操作系統(tǒng)的時候兩個應用程序進行消息傳遞一般使用全局變量的方式,但是如果在使用操作系統(tǒng)的應用中用全局變

    2024年02月11日
    瀏覽(26)
  • 【Linux】詳解進程通信中信號量的本質(zhì)&&同步和互斥的概念&&臨界資源和臨界區(qū)的概念

    【Linux】詳解進程通信中信號量的本質(zhì)&&同步和互斥的概念&&臨界資源和臨界區(qū)的概念

    ???????? 訪問資源在安全的前提下,具有一定的順序性,就叫做同步 。在多道程序系統(tǒng)中,由于資源有限,進程或線程之間可能產(chǎn)生沖突。同步機制就是為了解決這些沖突,保證進程或線程之間能夠按照既定的順序訪問共享資源。同步機制有助于避免競態(tài)條件和死鎖(

    2024年04月25日
    瀏覽(91)
  • 【STM32】FreeRTOS消息隊列和信號量學習

    【STM32】FreeRTOS消息隊列和信號量學習

    一、消息隊列(queue) 隊列是一種用于實現(xiàn)任務與任務之間,任務與中斷之間消息交流的機制。 注意:1.數(shù)據(jù)的操作是FIFO模式。 2.隊列需要明確數(shù)據(jù)的大小和隊列的長度。 3.寫和讀都會出現(xiàn)堵塞。 實驗:創(chuàng)建一個消息隊列,兩個發(fā)送任務,一個接收任務。 其中任務一任務三

    2024年02月13日
    瀏覽(17)
  • 學習系統(tǒng)編程No.22【消息隊列和信號量】

    學習系統(tǒng)編程No.22【消息隊列和信號量】

    北京時間:2023/4/20/7:48,鬧鐘6點和6點30,全部錯過,根本起不來,可能是因為感冒還沒好,睡不夠吧!并且今天是星期四,這個星期這是第二篇博客,作為一個日更選手,少些了兩篇博客,充分擺爛,但是擺爛具體也是有原因的,星期一的時候莫名高燒,頭昏腦漲的感覺,睡

    2023年04月27日
    瀏覽(17)
  • 【C++】Windows下共享內(nèi)存加信號量實現(xiàn)進程間同步通信

    【C++】Windows下共享內(nèi)存加信號量實現(xiàn)進程間同步通信

    目錄 一,函數(shù)清單 1.CreateFileMapping?方法 2.OpenFileMapping?方法 3.MapViewOfFile?方法 4.UnmapViewOfFile?方法 5.CreateSemaphore?方法 6.?OpenSemaphore?方法 7.WaitForSingleObject?方法 8.ReleaseSemaphore?方法 9.CloseHandle?方法 10.GetLastError?方法 二,單共享內(nèi)存單信號量-進程間單向通信 共享內(nèi)存管理文

    2024年02月08日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包