欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Linux systemV消息隊列和信號量詳解

 更新時間:2025年03月20日 09:46:12   作者:s_little_monster_  
這篇文章主要介紹了Linux systemV消息隊列和信號量,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

一、消息隊列

1、實現(xiàn)原理

操作系統(tǒng)在內(nèi)核建立一個隊列,通信的兩個進(jìn)程AB以數(shù)據(jù)塊的形式將需要發(fā)送的數(shù)據(jù)pushback到隊列中,數(shù)據(jù)塊是一個結(jié)構(gòu)體,其中有字段標(biāo)識該數(shù)據(jù)塊是誰發(fā)送的,所以我們只要讓不同的進(jìn)程看到同一個隊列就可以了

2、系統(tǒng)調(diào)用接口

(一)創(chuàng)建獲取一個消息隊列

msgget函數(shù)的主要功能是創(chuàng)建一個新的消息隊列或者獲取一個已經(jīng)存在的消息隊列的標(biāo)識符

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflg);

返回值:成功返回一個msgid,失敗返回-1

  • key:ftok函數(shù)的返回值
  • msgflg:標(biāo)識符
函數(shù)msgflg作用示例
msggetIPC_CREAT如果指定鍵對應(yīng)的消息隊列不存在,則創(chuàng)建一個新的消息隊列;若已存在,則直接返回該消息隊列的標(biāo)識符msgget(key, IPC_CREAT | 0666)
msggetIPC_EXCL通常與 IPC_CREAT 一起使用,若同時設(shè)置這兩個標(biāo)志,當(dāng)消息隊列已經(jīng)存在時,msgget 調(diào)用會失敗并返回 -1,errno 會被設(shè)置為 EEXISTmsgget(key, IPC_CREAT | IPC_EXCL | 0666)
msgget0600消息隊列的所有者具有讀寫權(quán)限,所屬組和其他用戶沒有任何權(quán)限msgget(key, 0600)
msgget0660消息隊列的所有者和所屬組具有讀寫權(quán)限,其他用戶沒有權(quán)限msgget(key, 0660)
msgget0666消息隊列的所有者、所屬組和其他用戶都具有讀寫權(quán)限msgget(key, 0666)

(二)控制消息隊列

msgctl用于控制消息隊列的系統(tǒng)調(diào)用函數(shù),通常用于對消息隊列執(zhí)行各種管理操作,如獲取消息隊列狀態(tài)、設(shè)置消息隊列屬性以及刪除消息隊列等

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgctl(int msgid, int cmd, struct msqid_ds *buf);

返回值:返回0表示操作成功,返回-1表示操作失敗

  • msgid:消息隊列標(biāo)識符,msgget函數(shù)返回值
  • cmdmsgctl函數(shù)的cmd參數(shù)常用命令如下:
命令說明
IPC_STAT獲取消息隊列的狀態(tài)信息,將信息存儲在buf指向的msqid_ds結(jié)構(gòu)中。這些信息包括消息隊列的權(quán)限、所有者信息、消息隊列的大小、當(dāng)前消息數(shù)量等
IPC_SET根據(jù)buf指向的msqid_ds結(jié)構(gòu)中的值,設(shè)置消息隊列的屬性??梢栽O(shè)置的屬性包括消息隊列的權(quán)限、隊列的最大字節(jié)數(shù)等
IPC_RMID刪除指定的消息隊列。調(diào)用該命令后,消息隊列將被立即刪除,所有排隊的消息都會被丟棄,并且與該消息隊列相關(guān)的資源也會被釋放
MSG_INFO獲取與消息隊列相關(guān)的系統(tǒng)資源使用信息,例如當(dāng)前系統(tǒng)中消息隊列的總數(shù)、系統(tǒng)允許的最大消息隊列數(shù)等
MSG_STAT該命令與IPC_STAT類似,但它返回的是一個指向struct msg_info結(jié)構(gòu)的指針,該結(jié)構(gòu)包含了更多關(guān)于消息隊列的統(tǒng)計信息,如發(fā)送和接收消息的字節(jié)數(shù)等
  • buf:一個指向msgid_ds結(jié)構(gòu)體的指針,用于存儲或提供消息隊列的相關(guān)信息,msqid_ds結(jié)構(gòu)包含了消息隊列的各種屬性,如隊列的權(quán)限、所有者信息、消息隊列的大小等

(三)發(fā)送消息

msgsnd用于向消息隊列發(fā)送消息的系統(tǒng)調(diào)用函數(shù),它允許進(jìn)程將一個消息添加到指定的消息隊列中

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg);

返回值:成功返回0,失敗返回-1

  • msgid:消息隊列標(biāo)識符,msgget函數(shù)返回值
  • msgp:指向要發(fā)送的消息結(jié)構(gòu)體的指針,該結(jié)構(gòu)體的第一個成員必須是 long 類型,用于指定消息的類型,后續(xù)可以包含消息的數(shù)據(jù)部分
  • msgsz:消息數(shù)據(jù)部分的長度,即msgp所指向結(jié)構(gòu)體中除第一個long類型成員之外的數(shù)據(jù)長度
  • msgflg:該位置為0就是不設(shè)置
函數(shù)msgflg作用示例
msgsndIPC_NOWAIT非阻塞發(fā)送消息,當(dāng)消息隊列已滿,無法立即發(fā)送消息時,如果設(shè)置了該標(biāo)志,msgsnd 函數(shù)會立即返回 -1,errno 被設(shè)置為 EAGAIN;若未設(shè)置該標(biāo)志,msgsnd 函數(shù)會阻塞,直到消息隊列有空間可以發(fā)送消息msgsnd(msgid, &msgbuf, sizeof(msgbuf.mtext), IPC_NOWAIT)

(四)在消息隊列中獲取數(shù)據(jù)塊

msgrcv用于從消息隊列接收消息的系統(tǒng)調(diào)用函數(shù),它允許進(jìn)程從指定的消息隊列中獲取消息

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
ssize_t msgrcv(int msgid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

返回值:成功返回實際收到的消息數(shù)據(jù)部分的字節(jié)數(shù),不包括最前面的long

前兩個參數(shù)與前面相同

  • msgsz:接收消息時用于存儲消息數(shù)據(jù)部分的緩沖區(qū)的最大長度
  • msgtyp:如果等于0,那該函數(shù)只接收消息隊列中的第一條消息,如果大于0,接收消息隊列中消息類型為msgtyp的第一條消息,如果小于0,接收消息隊列中消息類型小于等于msgtyp絕對值的最小類型的第一條消息
  • msgflg:該位置為0就是不設(shè)置
函數(shù)msgflg作用示例
msgrcvIPC_NOWAIT當(dāng)消息隊列中沒有符合要求的消息時,如果設(shè)置了該標(biāo)志,msgrcv 函數(shù)會立即返回 -1,errno 被設(shè)置為 ENOMSG;若未設(shè)置該標(biāo)志,msgrcv 函數(shù)會阻塞,直到有符合要求的消息進(jìn)入消息隊列msgrcv(msgid, &msgbuf, sizeof(msgbuf.mtext), msgtype, IPC_NOWAIT)
msgrcvMSG_NOERROR如果接收到的消息長度超過了指定的緩沖區(qū)大小,若設(shè)置了該標(biāo)志,消息會被截斷為緩沖區(qū)大小,多余部分會被丟棄,msgrcv 函數(shù)正常返回;若未設(shè)置該標(biāo)志,msgrcv 函數(shù)會返回 -1,errno 被設(shè)置為 E2BIGmsgrcv(msgid, &msgbuf, sizeof(msgbuf.mtext), msgtype, MSG_NOERROR)

二、信號量

1、原理

信號量是一種用于實現(xiàn)進(jìn)程間同步與互斥的機制,信號量本質(zhì)上是一個整數(shù)變量,用于控制對共享資源的訪問,它可以看作是一種特殊的計數(shù)器,其值表示當(dāng)前可用的共享資源數(shù)量,信號量的值可以被多個進(jìn)程或線程讀取和修改,通過對信號量的操作,進(jìn)程或線程可以協(xié)調(diào)對共享資源的訪問

信號量的工作基于兩個基本操作:P操作(wait操作)和V操作(signal操作)

  • P操作:當(dāng)一個進(jìn)程或線程需要訪問共享資源時,它會執(zhí)行 P 操作。P 操作會將信號量的值減 1,如果減 1 后信號量的值大于等于 0,表示當(dāng)前有可用的資源,進(jìn)程或線程可以繼續(xù)訪問;如果減 1 后信號量的值小于 0,表示沒有可用的資源,進(jìn)程或線程會被阻塞,直到有其他進(jìn)程或線程釋放資源
  • V 操作:當(dāng)一個進(jìn)程或線程使用完共享資源后,它會執(zhí)行 V 操作,V 操作會將信號量的值加 1,如果加 1 后信號量的值小于等于 0,表示有其他進(jìn)程或線程正在等待該資源,此時會喚醒一個等待的進(jìn)程或線程

2、系統(tǒng)調(diào)用接口

(一)創(chuàng)建獲取一個信號量

semget是用于創(chuàng)建或獲取信號量集的系統(tǒng)調(diào)用函數(shù)

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

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

返回值:成功返回信號量標(biāo)識符semid,失敗返回-1

  • nsems:表示要創(chuàng)建或獲取的信號量集中信號量的數(shù)量,如果是創(chuàng)建新的信號量集則必須大于 0,如果是獲取已有的信號量集則可以為0
  • semflg:標(biāo)志位,用于指定創(chuàng)建或獲取信號量集的方式和權(quán)限

(二)控制信號量

semctl是用于控制信號量集的系統(tǒng)調(diào)用函數(shù),它可以對信號量集進(jìn)行多種操作,如初始化信號量的值、獲取信號量的狀態(tài)、刪除信號量集等

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

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

返回值:取決于cmd的當(dāng)前值,對于 GETVAL 命令,返回指定信號量的當(dāng)前值,對于 IPC_STATIPC_SETIPC_RMID 等命令,返回 0 表示成功

  • semid:信號量標(biāo)識符,semget函數(shù)返回
  • semnum:信號量集中信號量的編號,編號從 0 開始,如果 cmd 操作不需要針對特定的信號量(如刪除整個信號量集),則可以忽略該參數(shù),通常將其設(shè)為 0
  • cmd:要執(zhí)行的命令,指定了對信號量集或特定信號量的操作類型

(三)PV操作

semop用于對信號量集執(zhí)行操作的系統(tǒng)調(diào)用函數(shù),它允許進(jìn)程對一個或多個信號量進(jìn)行原子性的 P和 V操作,從而實現(xiàn)進(jìn)程間的同步與互斥

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

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

返回值:成功返回0,失敗返回-1

  • sops:指向struct sembuf結(jié)構(gòu)體數(shù)組的指針,該數(shù)組包含了要對信號量集執(zhí)行的操作序列
  • nsopssops數(shù)組中元素的數(shù)量,即要執(zhí)行的操作序列的長度

三、systemV IPC方法的比較

1、描述IPC資源的結(jié)構(gòu)體

描述共享內(nèi)存IPC資源結(jié)構(gòu)體:

struct shmid_kernel /* private to the kernel */
{	
	struct kern_ipc_perm	shm_perm;
	struct file *		    shm_file;
	int						id;
	unsigned long			shm_nattch;
	unsigned long			shm_segsz;
	time_t					shm_atim;
	time_t					shm_dtim;
	time_t					shm_ctim;
	pid_t					shm_cprid;
	pid_t					shm_lprid;
	struct user_struct		*mlock_user;
};

描述消息隊列IPC資源結(jié)構(gòu)體:

struct msg_queue {
	struct kern_ipc_perm q_perm;
	time_t 				 q_stime;			/* last msgsnd time */
	time_t 				 q_rtime;			/* last msgrcv time */
	time_t				 q_ctime;			/* last change time */
	unsigned long 		 q_cbytes;			/* current number of bytes on queue */
	unsigned long		 q_qnum;			/* number of messages in queue */
	unsigned long		 q_qbytes;			/* max number of bytes on queue */
	pid_t				 q_lspid;			/* pid of last msgsnd */
	pid_t				 q_lrpid;			/* last receive pid */

	struct list_head 	 q_messages;
	struct list_head	 q_receivers;
	struct list_head	 q_senders;
};

描述信號量IPC資源結(jié)構(gòu)體:

struct sem_array {
	struct kern_ipc_perm	sem_perm;			/* permissions .. see ipc.h */
	time_t					sem_otime;			/* last semop time */
	time_t					sem_ctime;			/* last change time */
	struct sem				*sem_base;			/* ptr to first semaphore in array */
	struct sem_queue		*sem_pending;		/* pending operations to be processed */
	struct sem_queue		**sem_pending_last; /* last pending operation */
	struct sem_undo			*undo;				/* undo requests on this array */
	unsigned long			sem_nsems;			/* no. of semaphores in array */
};

他們有一個同樣的特點就是第一個參數(shù)都是struct kern_ipc_perm類型的

struct kern_ipc_perm
{
	spinlock_t		lock;
	int				deleted;
	key_t			key;
	uid_t			uid;
	gid_t			gid;
	uid_t			cuid;
	gid_t			cgid;
	mode_t			mode; 
	unsigned long	seq;
	void			*security;
};

2、操作系統(tǒng)對IPC資源進(jìn)行管理

所有的IPC資源都有一個struct kern_ipc_perm結(jié)構(gòu),所以操作系統(tǒng)通過數(shù)組將這些struct kern_ipc_perm結(jié)構(gòu)組織起來

ipc_ids是 Linux 內(nèi)核中用于管理IPC資源的核心數(shù)據(jù)結(jié)構(gòu)

struct ipc_ids {
    int             in_use;//記錄當(dāng)前系統(tǒng)中正在使用的IPC資源的數(shù)量
    int             max_id;//表示系統(tǒng)中允許的最大IPC標(biāo)識符值
    unsigned short  seq;//是一個序列號,用于生成唯一的IPC標(biāo)識符
    unsigned short  seq_max;//是序列號的最大值
    struct          semaphore sem;//這是一個信號量,用于對IPC資源的并發(fā)訪問進(jìn)行同步控制    
    struct          ipc_id_ary nullentry;//一個空的ipc_id_ary結(jié)構(gòu)
    struct          ipc_id_ary* entries;//指向ipc_id_ary結(jié)構(gòu)體的指針
};
struct ipc_id_ary {
    int    size;
    struct kern_ipc_perm *p[0];
};

這里的柔性數(shù)組p的作用就是維護(hù)當(dāng)前操作系統(tǒng)中所有IPC資源,我們通過強制類型轉(zhuǎn)換來通過這個數(shù)組里存的struct ipc_id_ary*找到具體的IPC對象,因為kern_ipc_perm是這三個結(jié)構(gòu)體中的第一個成員,我們只要知道了一個kern_ipc_perm的地址,就相當(dāng)于知道了某個具體IPC對象的起始地址,然后通過強制類型轉(zhuǎn)換就可以訪問到該IPC對象中的所有成員屬性,這樣就實現(xiàn)了對一個具體IPC對象的訪問,如((struct shmid_kernel*)p[0])->q_stime,在kern_ipc_perm中有字段來標(biāo)識該kern_ipc_perm是屬于哪種IPC資源,操作系統(tǒng)就知道要將其強制轉(zhuǎn)化成什么類型了,我們在用戶層面上使用的:shmid、msqidsemid在內(nèi)核上看就是p數(shù)組的下標(biāo)

ipc_id_arry屬于操作系統(tǒng),不屬于任何進(jìn)程,數(shù)組下標(biāo)是線性遞增的,但不會因為IPC資源的釋放而改變它的遞增屬性,即當(dāng)前操作系統(tǒng)中最后一個IPC資源的下標(biāo)是100,釋放掉這個IPC資源,下一次再創(chuàng)建IPC資源的時候它的下標(biāo)是101,而不是100,當(dāng)遞增到一定值的時候,會回到0

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • CentOS 7 中firewall-cmd命令詳細(xì)介紹

    CentOS 7 中firewall-cmd命令詳細(xì)介紹

    這篇文章主要介紹了 CentOS 7 中firewall-cmd命令詳細(xì)介紹的相關(guān)資料,這里對CentOS 7的firewall-cmd命令一一介紹,希望能幫助開始使用的朋友,需要的朋友可以參考下
    2016-11-11
  • Flume環(huán)境部署和配置詳解及案例大全

    Flume環(huán)境部署和配置詳解及案例大全

    flume是一個分布式、可靠、和高可用的海量日志采集、聚合和傳輸?shù)南到y(tǒng)。支持在日志系統(tǒng)中定制各類數(shù)據(jù)發(fā)送方,用于收集數(shù)據(jù);同時,F(xiàn)lume提供對數(shù)據(jù)進(jìn)行簡單處理,并寫到各種數(shù)據(jù)接受方(比如文本、HDFS、Hbase等)的能力 。
    2014-08-08
  • Linux使用sed命令替換字符串教程

    Linux使用sed命令替換字符串教程

    在本篇文章中小編給大家分享了關(guān)于Linux下如何使用sed命令替換字符串的相關(guān)知識點內(nèi)容,有需要的朋友們學(xué)習(xí)下。
    2019-01-01
  • windows 10 + vwware+centos 6.5虛擬機系統(tǒng)安裝Tomcat

    windows 10 + vwware+centos 6.5虛擬機系統(tǒng)安裝Tomcat

    這篇文章主要介紹了windows 10 + vwware+centos 6.5虛擬機系統(tǒng)安裝Tomcat的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • Linux搭建Docker環(huán)境全過程

    Linux搭建Docker環(huán)境全過程

    這篇文章主要介紹了Linux搭建Docker環(huán)境全過程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • 基于linux配置selenium環(huán)境并實現(xiàn)運行

    基于linux配置selenium環(huán)境并實現(xiàn)運行

    這篇文章主要介紹了基于linux配置selenium環(huán)境并實現(xiàn)運行,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-08-08
  • Linux中使用Cron定時執(zhí)行SQL任務(wù)的實現(xiàn)步驟

    Linux中使用Cron定時執(zhí)行SQL任務(wù)的實現(xiàn)步驟

    在Linux系統(tǒng)中,計劃任務(wù)(Cron)是一種強大的工具,可以自動執(zhí)行預(yù)定的任務(wù),它非常適合定期運行腳本、備份數(shù)據(jù)、清理臨時文件等一系列重復(fù)性任務(wù),本文給大家介紹了如何在Linux中使用Cron定時執(zhí)行SQL任務(wù),需要的朋友可以參考下
    2024-11-11
  • Apache ab并發(fā)負(fù)載壓力測試實現(xiàn)方法

    Apache ab并發(fā)負(fù)載壓力測試實現(xiàn)方法

    Apache的ab命令模擬多線程并發(fā)請求,測試服務(wù)器負(fù)載壓力,也可以測試nginx、lighthttp、IIS等其它Web服務(wù)器的壓力
    2019-09-09
  • Linux zabbix自定義監(jiān)控及報警實現(xiàn)過程解析

    Linux zabbix自定義監(jiān)控及報警實現(xiàn)過程解析

    這篇文章主要介紹了linux zabbix自定義監(jiān)控及報警實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-08-08
  • kali?linux?無法登錄root的問題及解決方法

    kali?linux?無法登錄root的問題及解決方法

    這篇文章主要介紹了kali?linux?無法登錄root的問題及解決方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2025-04-04

最新評論