UNPV2 学习:System V IPC 章节学习问题记录

环境信息

OS:debian11
kernel:linux kernel 5.15

linux 环境测试时附录源代码修改

#ifndef MSG_R
#define SVMSG_MODE (FILE_MODE)
#else
#define	SVMSG_MODE	(MSG_R | MSG_W | MSG_R>>3 | MSG_R>>6)
#endif

linux 上 System V IPC 实现的一些特点

查看 System V IPC 占用率

可以使用 lspic 来查询 System V IPC 状态信息,示例如下:

RESOURCE DESCRIPTION                                              LIMIT USED  USE%
MSGMNI   Number of message queues                                 32000   10 0.03%
MSGMAX   Max size of message (bytes)                               8192    -     -
MSGMNB   Default max size of queue (bytes)                        16384    -     -
..................................................................................

缺省的限制为 32000,lspic 能够显示消息队列的使用情况,在上面的实例中,有 10 个消息队列被使用,占用率约为 0.03%。

System V IPC 的释放

创建 System V IPC 的进程退出时内核不会回收 ipc,除非主动调用释放函数。ipc id 泄露完了后,再次尝试创建会报如下错误:

msgget error: No space left on device

lsipc 能够看到如下内容:

[longyu@debian:12:36:21] svmsg $ lsipc
RESOURCE DESCRIPTION                                              LIMIT  USED    USE%
MSGMNI   Number of message queues                                 32000 32000 100.00%
.....................................................................................

32000 个 id 已经被分配,占用率为 100%。
man msgget 得到如下描述信息:

MSGMNI System-wide limit on the number of message queues.  Before Linux 3.19, the default value for this limit was calculated using  a  formula
              based  on  available  system  memory.  Since Linux 3.19, the default value is 32,000.  On Linux, this limit can be read and modified via
              /proc/sys/kernel/msgmni.

msgmni 可以动态修改,允许修改的值有限定,比 32000 小可以正常配置,比 32000 大,需要符合特定的规律才能设定。

[longyu@debian:12:54:17] kernel $ sudo su  -c   'echo 32600 > msgmni '
[longyu@debian:12:54:32] kernel $ cat ./msgmni 
32600

921271566
1102226159

linux 内核代码中对 System V IPC id 的描述信息

 18 /*
 19  * The IPC ID contains 2 separate numbers - index and sequence number.
 20  * By default,
 21  *   bits  0-14: index (32k, 15 bits)
 22  *   bits 15-30: sequence number (64k, 16 bits)
 23  *
 24  * When IPCMNI extension mode is turned on, the composition changes:
 25  *   bits  0-23: index (16M, 24 bits)
 26  *   bits 24-30: sequence number (128, 7 bits)
 27  */

linux 内核的 IPC ID 由 index 与 sequence number 两部分数值拼接而成。默认配置下这两部分数值关系如下:

  1. 低 0-14 位,共计 15 位为 index 的值
  2. 高 15-30 位,共计 16 位为 sequence number 的值

当 IPCMNI 扩展模式使能时,IPC id 值的生成规则如下:

  1. 低 0-23 位,共计 24 位为 index 的值
  2. 高 24-30 位为 sequence number 的值

Exercises 3.1:获取 ipc_perm 与 seq number 的值

示例代码:

int
main(int argc, char **argv)
{
	int		i, msqid;
	struct msqid_ds info;

	for (i = 0; i < 20; i++) {
		msqid = Msgget(IPC_PRIVATE, SVMSG_MODE | IPC_CREAT);
		printf("msqid = %d\n", msqid);
		Msgctl(msqid, IPC_STAT, &info);
		
		printf("ipc_perm seq number is %d\n", info.msg_perm.__seq);
		Msgctl(msqid, IPC_RMID, NULL);
	}

	exit(0);
}

运行结果如下:

msqid = 921370624
ipc_perm seq number is 28118
msqid = 921370625
............................
ipc_perm seq number is 28119
msqid = 921403393

每 64 个 msqid seq 递增一次。数字上的关系为 seq * 512 * 64 + 1 为下一组 64 个 msgid 的起始值。

10 进制与 2 进制对比:

110110111010110 28118
110110111010110000000000000001 921370625

能够发现 28118 是 921370625 的高 15 位值。

Exercises 3.2:msq 每次获取返回的 id 值的变化特点

测试记录
0~63
32768-32831
65536- 65599
98304-98367

每 64 个 id 值为一组连续空间,超过 64 后起始值按照某种规律重新生成。

Exercises3.3:创建 fifo 与 msgq 时对 umask 的使用

umask 的值:0022
示例代码:

int		i, msqid;

#define TEST_FIFOPATH "/tmp/test_fifo"
	struct msqid_ds info;
	struct stat statbuf;

	mkfifo(TEST_FIFOPATH, 0666);
	stat(TEST_FIFOPATH, &statbuf);
	unlink(TEST_FIFOPATH);
	printf("fifo perm is %o\n", statbuf.st_mode);

	msqid = Msgget(IPC_PRIVATE, 0666 | IPC_CREAT);
	Msgctl(msqid, IPC_STAT, &info);
	Msgctl(msqid, IPC_RMID, NULL);
	printf("msgq perm is %o\n", info.msg_perm.mode);

测试结果:

fifo perm is 10644
msgq perm is 666

system V ipc 消息队列创建时不会使用 umask 来去除必要的权限,fifo 在创建时会使用 umask 去掉必要的权限。

man mkfifo 得到的信息:

DESCRIPTION
       mkfifo()  makes a FIFO special file with name pathname.  mode specifies the FIFO's permissions.  It is modified by the process's umask
       in the usual way: the permissions of the created file are (mode & ~umask).q

man msgget 未搜索到任何与 umask 相关的内容与测试结果一致。

Exercises3.4:服务端为客户端创建唯一消息队列时那种方式更适用?

1. 使用程序名作为固定的路径名作为参数用 ftok 生成 key 来创建

在这种方式下,编码约定、引入三方通信框架将路径名代表的消息队列通知客户端,客户端使用相同的路径名用 ftok 生成 key 获取 server 创建的消息队列。当需要创建多个消息队列时,需要指定多个路径以区分不同的实例。

2. 使用 IPC_PRIVATE 标志让内核自行分配 id 创建

在这种方式下,服务端与客户端之间需要依赖第三方的通信框架以将消息队列的标识符通知客户端,当有多个客户端时,使用这种方式避免了第一种方式中提供多个文件路径的行为,然而此种方式却不能简单的通过编码约定来关联同一个消息队列。

Exercises3.5:使用 find 批量化查找文件并制作参数使用 ftok 生成 key

示例命令:

find / -print   | xargs -i ./svipc/ftok '{}' > output

初步观察未找到相同的 key。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
GeoPandas是一个开源的Python库,旨在简化地理空间数据的处理和分析。它结合了Pandas和Shapely的能力,为Python用户提供了一个强大而灵活的工具来处理地理空间数据。以下是关于GeoPandas的详细介绍: 一、GeoPandas的基本概念 1. 定义 GeoPandas是建立在Pandas和Shapely之上的一个Python库,用于处理和分析地理空间数据。 它扩展了Pandas的DataFrame和Series数据结构,允许在其中存储和操作地理空间几何图形。 2. 核心数据结构 GeoDataFrame:GeoPandas的核心数据结构,是Pandas DataFrame的扩展。它包含一个或多个列,其中至少一列是几何列(geometry column),用于存储地理空间几何图形(如点、线、多边形等)。 GeoSeries:GeoPandas中的另一个重要数据结构,类似于Pandas的Series,但用于存储几何图形序列。 二、GeoPandas的功能特性 1. 读取和写入多种地理空间数据格式 GeoPandas支持读取和写入多种常见的地理空间数据格式,包括Shapefile、GeoJSON、PostGIS、KML等。这使得用户可以轻松地从各种数据源中加载地理空间数据,并将处理后的数据保存为所需的格式。 2. 地理空间几何图形的创建、编辑和分析 GeoPandas允许用户创建、编辑和分析地理空间几何图形,包括点、线、多边形等。它提供了丰富的空间操作函数,如缓冲区分析、交集、并集、差集等,使得用户可以方便地进行地理空间数据分析。 3. 数据可视化 GeoPandas内置了数据可视化功能,可以绘制地理空间数据的地图。用户可以使用matplotlib等库来进一步定制地图的样式和布局。 4. 空间连接和空间索引 GeoPandas支持空间连接操作,可以将两个GeoDataFrame按照空间关系(如相交、包含等)进行连接。此外,它还支持空间索引,可以提高地理空间数据查询的效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值