linux 消息对lie_Linux消息队列之原理实现篇(转)

Linux的消息队列(queue)实质上是一个链表, 它有消息队列标识符(queue ID). msgget创建一个新队列或打开一个存在的队列; msgsnd向队列末端添加一条新消息; msgrcv从队列中取消息, 取消息是不一定遵循先进先出的, 也可以按消息的类型字段取消息.

1. 标识符(des)和键(key):

消息队列, 信号量和共享存储段, 都属于内核中的IPC结构, 它们都用标识符来描述. 这个标识符是一个非负整数, 与文件描述符不同的是, 创建时并不会重复利用通过删除回收的整数, 而是每次+1, 直到整数最大值回转到0.

标识符是IPC对象的内部名, 而它的外部名则是key(键), 它的基本类型是key_t, 在头文件中定义为长整型. 键由内核变换成标识符.

2. 消息队列状态msqid_ds:

每个消息队列都有一个msqid_ds结构与其关联:

struct msqid_ds

...{

struct ipc_perm msg_perm; /**//* access */

msgqnum_t        msg_qnum; /**//* # of messages on queue */

msglen_t            msg_qbytes; /**//* max # of bytes on queue */

pid_t                  msg_lspid;  /**//* pid of last msgsnd() */

pid_t                  msg_lrpid;  /**//* pid of last msgrcv() */

time_t                msg_stime; /**//* last-msgsnd() time */

time_t                msg_rtime; /**//* last-msgrcv() time */

time_t                msg_ctime; /**//* last-change time */

...

...

...

};

3. 由路径名和项目ID产生一个key:

如果客户进程和服务器进程认同一个路径名和项目ID(0~255间的字符值), 接着调用ftok将这两个值变换为一个key.

原型: key_t ftok(const char *path, int id);

头文件:

返回值: 成功则返回key, 出错则返回(key_t)-1.

参数: path参数必须引用一个现存文件. 当产生key时 只使用id参数的低8位.

说 明: 如果两个路径名引用两个不同的文件, 对这两个路径名调用ftok通常返回不同的key. 但是, 因为i节点号和key通常存放在长整型中, 于是创建key时可能会丢失信息. 这意味着, 如果使用同一项目ID, 那么对于不同文件的两个路径名可能产生相同的key. 该函数的工作方式为:

按给定的路径名取得其stat结构.

从该结构中取出部分st_dev和st_ino字段, 与项目ID组合起来.

4. 创建/打开消息队列:

msgget可以创建一个新队列或打开一个存在的队列.

原型: int msgget(key_t key, int flag);

头文件:

返回值: 成功则返回消息队列ID, 出错则返回-1.

参数:

key: 消息队列的key值.

flag: 标志位.

说明:

创建队列有两种方法:

key是IPC_PRIVATE.

key当前未与特定类型的IPC结构相结合, 并且flag中指定了IPC_CREAT位.

初始化msqid_ds成员:

ipc_perm中的mode成员按flag进行设置.

msg_qnum, msg_lspid, msg_lrpid, msg_stime和msg_rtime都设置为0.

msg_ctime设置为当前时间.

msg_qbytes设置为系统限制值.

5. 消息队列的垃圾桶函数:

msgctl类似于驱动程序中的ioctl函数, 可对消息队列执行多种操作.

原型: int msgctl(int msqid, int cmd, struct msgqid_ds *buf);

头文件:

返回值: 成功则返回0, 出错则返回-1.

参数: cmd参数说明对msqid指定的队列要执行的命令:

IPC_STAT: 取此队列的msqid_ds结构, 并将它存放在buf指向的结构中.

IPC_SET: 按由buf指向结构中的值, 设置与此队列相关结构中的msg_perm.uid, msg_perm.gid, msg_perm.mode和msg_qbytes. 该命令只有下列两种进程可以执行:

有效用户ID等于msg_perm.cuid或msg_per.uid.

具有超级用户特权的进程.

IPC_RMID: 从系统中删除该消息队列以及仍在该队列中的所有数据. 执行权限同上.

6. 将数据放到消息队列:

调用msgsnd将数据放到消息队列中.

原型: int msgsnd(int msqid, const void *ptr, size_t nbytes, int flag);

头文件:

返回值: 成功则返回0, 出错则返回-1.

说 明: 可以定义一个消息结构, 结构中带类型, 这样就可用非先进先出顺序取消息了. 当msgsnd成功返回, 与消息队列相关的msqid_ds结构得到更新, 以标明发出该调用的进程ID(msg_lsqid), 进行该调用的时间(msg_stime), 并指示队列中增加了一条消息(msg_qnum).

7. 从消息队列中取消息:

调用msgrcv将从消息队列中取消息.

原型: ssize_t msgrcv(int msqid, void *ptr, size_t nbytes, long type, int flag);

头文件:

返回值: 成功则返回消息的数据部分的长度, 出错则返回-1.

参数:

ptr: 指向一个长整型数(返回的消息类型存放在其中), 跟随其后的是存放实际消息数据的缓冲区.

nbytes: 数据缓冲区的长度. 若返回的消息大于nbytes, 且在flag中设置了MSG_NOERROR, 则该消息被截短.

type:

type == 0: 返回队列中的第一个消息.

type > 0: 返回队列中消息类型为type的第一个消息.

type < 0: 返回队列中消息类型值小于或等于type绝对值的消息, 如果这种消息有若干个, 则取类型值最小的消息.

说明: 当msgrcv成功返回时, 与消息队列相关的msqid_ds结构被更新, 以指示调用者的进程ID(msg_lrpid), 调用时间(msg_rtime)和队列中的消息数(msg_qnum)减1.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 为了安装mysql-8.0.33-linux-glibc2.28-x86_64.tar.gz,你可以按照以下步骤进行操作。首先,解压文件并将其移动到指定目录。在Linux环境下,你可以使用以下命令解压文件并移动到指定目录: \[root@dev1 opt\]# tar xvJf mysql-8.0.33-linux-glibc2.28-x86_64.tar.gz \[root@dev1 opt\]# mv mysql-8.0.33-linux-glibc2.28-x86_64 mysql-8.0.33 \[1\] 接下来,创建配置文件my.cnf。在Windows环境下,你可以新建my.ini文件,并按照以下设置指定基本安装目录(basedir)、数据存放目录(datadir)以及端口号(port): \[mysqld\] port=3307 basedir=D:\\mysql-8.0.33-winx64 datadir=D:\\mysql-8.0.33-winx64\\data \[2\] 然后,启动MySQL服务。在Linux环境下,你可以使用以下命令启动MySQL服务: \[root@dev1 mysql-8.0.33\]# systemctl start mysqld80 \[3\] 最后,检查MySQL服务是否已成功启动。你可以使用以下命令检查MySQL服务的监听端口: \[root@dev1 mysql-8.0.33\]# netstat -lntup|grep mysqld tcp6 0 0 :::33060 :::* LISTEN 9129/mysqld tcp6 0 0 :::3305 :::* LISTEN 7479/mysqld tcp6 0 0 :::3308 :::* LISTEN 9129/mysqld \[3\] 最后,你可以设置MySQL服务为自启动,以确保在系统重启后自动启动MySQL服务。 请注意,以上步骤仅适用于Linux和Windows环境下的安装和配置。如果你使用的是其他操作系统,请参考相应的文档进行安装和配置。 #### 引用[.reference_title] - *1* *3* [CentOS7 安装mysql8.0 glibc版,tar.gz,tar.xz](https://blog.csdn.net/haveqing/article/details/124744179)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Windows 11 和 Rocky 9 Linux 平台 MySQL 8.0.33 简易安装教程](https://blog.csdn.net/A_Z_Lie/article/details/130835581)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值