亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Linux systemV消息隊(duì)列和信號(hào)量詳解

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

一、消息隊(duì)列

1、實(shí)現(xiàn)原理

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

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

(一)創(chuàng)建獲取一個(gè)消息隊(duì)列

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

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

返回值:成功返回一個(gè)msgid,失敗返回-1

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

(二)控制消息隊(duì)列

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

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

(三)發(fā)送消息

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

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

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

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

#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í)際收到的消息數(shù)據(jù)部分的字節(jié)數(shù),不包括最前面的long

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

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

二、信號(hào)量

1、原理

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

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

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

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

(一)創(chuàng)建獲取一個(gè)信號(hào)量

semget是用于創(chuàng)建或獲取信號(hào)量集的系統(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);

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

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

(二)控制信號(hào)量

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

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

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

返回值:取決于cmd的當(dāng)前值,對(duì)于 GETVAL 命令,返回指定信號(hào)量的當(dāng)前值,對(duì)于 IPC_STAT、IPC_SETIPC_RMID 等命令,返回 0 表示成功

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

(三)PV操作

semop用于對(duì)信號(hào)量集執(zhí)行操作的系統(tǒng)調(diào)用函數(shù),它允許進(jìn)程對(duì)一個(gè)或多個(gè)信號(hào)量進(jìn)行原子性的 P和 V操作,從而實(shí)現(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ù)組包含了要對(duì)信號(hào)量集執(zhí)行的操作序列
  • nsopssops數(shù)組中元素的數(shù)量,即要執(zhí)行的操作序列的長(zhǎng)度

三、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;
};

描述消息隊(duì)列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;
};

描述信號(hào)量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 */
};

他們有一個(gè)同樣的特點(diǎn)就是第一個(gè)參數(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)對(duì)IPC資源進(jìn)行管理

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

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)識(shí)符值
    unsigned short  seq;//是一個(gè)序列號(hào),用于生成唯一的IPC標(biāo)識(shí)符
    unsigned short  seq_max;//是序列號(hào)的最大值
    struct          semaphore sem;//這是一個(gè)信號(hào)量,用于對(duì)IPC資源的并發(fā)訪問(wèn)進(jìn)行同步控制    
    struct          ipc_id_ary nullentry;//一個(gè)空的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資源,我們通過(guò)強(qiáng)制類型轉(zhuǎn)換來(lái)通過(guò)這個(gè)數(shù)組里存的struct ipc_id_ary*找到具體的IPC對(duì)象,因?yàn)?code>kern_ipc_perm是這三個(gè)結(jié)構(gòu)體中的第一個(gè)成員,我們只要知道了一個(gè)kern_ipc_perm的地址,就相當(dāng)于知道了某個(gè)具體IPC對(duì)象的起始地址,然后通過(guò)強(qiáng)制類型轉(zhuǎn)換就可以訪問(wèn)到該IPC對(duì)象中的所有成員屬性,這樣就實(shí)現(xiàn)了對(duì)一個(gè)具體IPC對(duì)象的訪問(wèn),如((struct shmid_kernel*)p[0])->q_stime,在kern_ipc_perm中有字段來(lái)標(biāo)識(shí)該kern_ipc_perm是屬于哪種IPC資源,操作系統(tǒng)就知道要將其強(qiáng)制轉(zhuǎn)化成什么類型了,我們?cè)谟脩魧用嫔鲜褂玫模?code>shmid、msqid、semid在內(nèi)核上看就是p數(shù)組的下標(biāo)

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

總結(jié)

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

相關(guān)文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Linux zabbix自定義監(jiān)控及報(bào)警實(shí)現(xiàn)過(guò)程解析

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

    kali?linux?無(wú)法登錄root的問(wèn)題及解決方法

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

最新評(píng)論