当前位置: 首页 > news >正文

茶企业网站建设模板搭建一个网站需要什么

茶企业网站建设模板,搭建一个网站需要什么,中企动力科技股份有限公司深圳分公司,朗格手表网站文章目录 前言:🎃消息队列:1. **消息队列的基本概念**2. **消息队列的特点**3. **常见的消息队列操作(Linux IPC)****1) msgget:创建或获取消息队列****2) msgsnd:发送消息****3) msgrcv&#x…

文章目录

  • 前言:
  • 🎃消息队列:
      • 1. **消息队列的基本概念**
      • 2. **消息队列的特点**
      • 3. **常见的消息队列操作(Linux IPC)**
        • **1) `msgget`:创建或获取消息队列**
        • **2) `msgsnd`:发送消息**
        • **3) `msgrcv`:接收消息**
        • **4) `msgctl`:控制消息队列**
      • 4. **消息队列的基本操作示例(Linux C代码)**
        • **消息发送示例**:
        • **消息接收示例**:
        • **删除消息队列**:
      • 5. **消息队列的优缺点**
        • **优点**:
        • **缺点**:
      • 6. **消息队列的应用场景**
  • 🎃信号量:
    • ❤️五个概念:
    • ❤️对信号量的理解?
      • 🍤对于不整体使用的资源:
      • 🍚对于整体使用的资源:
      • 🍗那我可不可以使用全局变量?
  • OS是如何把共享内存、消息队列、信号量统一管理起来的?

前言:

关于System V下的通信方式,我们只是对共享内存做深度的处理,而对于消息队列和信号量我们并不会特别在意,一下我将粗略的介绍一下关于消息队列,但是信号量这一部分,还有一些新的知识点需要好好聊聊。

🎃消息队列:

消息队列(Message Queue)是操作系统提供的一种进程间通信(IPC,Inter-Process Communication)机制,允许进程通过消息的形式进行异步通信。消息队列为进程间提供了一个有序的、独立于进程之外的消息缓冲区,进程可以通过向消息队列发送和接收消息来进行数据交换。

1. 消息队列的基本概念

  • 异步通信:消息发送进程和接收进程之间是异步的,即发送者可以发送消息后立即返回,无需等待接收者处理;同样,接收者在准备好时可以读取消息,而无需等待发送者。
  • 持久性:消息队列中的消息是持久的,消息一旦被发送,它们会保留在队列中,直到被接收进程读取或队列被显式删除。
  • 顺序性:消息以队列的形式存储,发送的顺序决定了消息的顺序。接收者可以按照消息的优先级或先进先出的顺序读取消息。

2. 消息队列的特点

  • 异步通信:消息队列允许发送进程和接收进程以不同时执行,发送进程不需要等待接收进程处理消息。
  • 持久性:消息队列是内核管理的,在消息被读取之前,它们会一直保存在队列中,即使发送者和接收者都已经终止。
  • 消息有优先级:消息可以按照优先级或FIFO(先进先出)的方式传递,接收者可以按优先级顺序或按时间顺序接收消息。

3. 常见的消息队列操作(Linux IPC)

在Linux中,消息队列是通过系统调用来实现的。下面是与消息队列相关的常见系统调用及其功能:

1) msgget:创建或获取消息队列
int msgget(key_t key, int msgflg);
  • key:消息队列的唯一标识符,由用户定义。可以通过ftok()函数生成。
  • msgflg:消息队列的标志位。可以是IPC_CREAT(如果消息队列不存在则创建),以及权限标志如0666等。
  • 返回值:返回消息队列的标识符(msqid),后续操作基于此ID。
2) msgsnd:发送消息
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
  • msqid:消息队列标识符,由msgget()返回。
  • msgp:指向消息结构体的指针,该结构体包含消息类型和消息内容。
  • msgsz:消息的大小。
  • msgflg:控制操作的标志位。如果队列满了,IPC_NOWAIT可以避免发送者被阻塞。
  • 返回值:成功时返回0,失败时返回-1并设置errno

消息结构通常定义如下:

struct msgbuf {long mtype;       // 消息类型char mtext[1];    // 消息内容
};
3) msgrcv:接收消息

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
  • msqid:消息队列标识符。
  • msgp:指向存储接收消息的结构体的指针。
  • msgsz:要接收的最大消息大小。
  • msgtyp:指定要接收的消息类型。如果为0,则接收队列中的第一条消息。
  • msgflg:控制操作的标志位。可以使用IPC_NOWAIT来防止阻塞,或者使用MSG_EXCEPT来接收非指定类型的消息。
  • 返回值:返回读取到的字节数,失败时返回-1并设置errno
4) msgctl:控制消息队列

int msgctl(int msqid, int cmd, struct msqid_ds *buf);
  • msqid:消息队列标识符。

  • cmd

    :控制操作,可以是以下值:

    • IPC_STAT:获取消息队列的状态。
    • IPC_SET:设置消息队列的状态。
    • IPC_RMID:删除消息队列。
  • buf:用于存储或设置消息队列的状态信息,msqid_ds结构体包含权限、最后的操作时间、消息数等信息。

4. 消息队列的基本操作示例(Linux C代码)

以下是一个简单的消息队列示例代码,展示如何创建消息队列、发送消息和接收消息。

消息发送示例
c复制代码#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>struct msgbuf {long mtype;        // 消息类型char mtext[100];   // 消息内容
};int main() {key_t key;int msgid;// 生成唯一的keykey = ftok("progfile", 65);// 创建消息队列msgid = msgget(key, 0666 | IPC_CREAT);// 准备要发送的消息struct msgbuf message;message.mtype = 1; // 消息类型strcpy(message.mtext, "Hello World!");// 发送消息到队列msgsnd(msgid, &message, sizeof(message.mtext), 0);printf("Message Sent: %s\n", message.mtext);return 0;
}
消息接收示例
c复制代码#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>struct msgbuf {long mtype;        // 消息类型char mtext[100];   // 消息内容
};int main() {key_t key;int msgid;// 生成唯一的keykey = ftok("progfile", 65);// 获取消息队列msgid = msgget(key, 0666 | IPC_CREAT);// 准备接收消息struct msgbuf message;// 接收类型为1的消息msgrcv(msgid, &message, sizeof(message.mtext), 1, 0);// 显示消息内容printf("Message Received: %s\n", message.mtext);return 0;
}
删除消息队列
c复制代码#include <sys/ipc.h>
#include <sys/msg.h>int main() {key_t key;int msgid;// 生成唯一的keykey = ftok("progfile", 65);// 获取消息队列msgid = msgget(key, 0666 | IPC_CREAT);// 删除消息队列msgctl(msgid, IPC_RMID, NULL);return 0;
}

5. 消息队列的优缺点

优点
  • 异步处理:发送进程不必等待接收进程,可以提高系统的并发性和响应能力。
  • 持久性:消息在队列中保存,直到接收者取走消息或队列被删除,即使发送者和接收者的生命周期不同步。
  • 易用性:消息队列通过消息类型支持不同的消息分类,允许接收进程选择性读取某一类型的消息。
缺点
  • 容量限制:消息队列有大小限制,如果消息队列已满,发送进程可能会被阻塞(除非设置非阻塞标志)。
  • 管理复杂性:消息队列是内核资源,使用后需要手动清理,未清理的消息队列可能会长期占用系统资源。
  • 不适合大量数据传输:消息队列更适合传递较小的数据,过大的数据块可能会影响系统性能。

6. 消息队列的应用场景

  • 进程间通信:消息队列用于不同进程之间的数据交换,例如不同模块之间的数据传递。
  • 任务调度:某些系统通过消息队列进行任务调度,工作进程从队列中取任务执行。
  • 日志系统:系统日志可以通过消息队列集中到一个日志处理进程来进行统一的日志存储或分析。

消息队列是一种常用的进程间通信机制,支持异步数据传输和灵活的消息管理。通过msggetmsgsndmsgrcv等系统调用,进程可以方便地将消息发送到队列中并从中读取消息。虽然消息队列有一些限制,比如队列大小的限制和内核资源的消耗,但它在许多系统中仍然是一个高效的通信工具。

🎃信号量:

❤️五个概念:

  1. 多个进程(执行流)想要实现通信,都必须在内核中看到同一份资源,这个资源成为公共资源(共享资源)。
  2. 而被保护起来的资源就叫——临界资源
  3. 而保护的方式分为同步和互斥,而互斥是任何一个时刻只能有一个进程在访问公共资源。而以互斥方式保护的共享资源就是临界资源。
  4. 资源一定是要被访问的,而且是通过代码访问的。(代码又会分为“存在访问共享资源的”和“不存在访问共享资源的”。对于上述这两种情况,分别称为——临界区和非临界区。
  5. 所谓利用互斥保护共享资源使其变为临界资源,本质是对访问共享资源的代码进行保护
    image-20241018102233046

❤️对信号量的理解?

信号量(Semaphore)是一种用于控制对共享资源的访问的同步机制,广泛应用于多线程和多进程编程中。信号量可以用来解决临界区问题,防止竞争条件,并确保资源的互斥访问。(简单来说,是用来保护临界资源的)

🍤对于不整体使用的资源:

image-20241018112219718

所以对临界资源的保护其实就是设置一个计数器,每次访问前先申请访问,访问通过了才能访问,访问完成后又会有一个退出操作。因此保护临界资源的信号量本质就是一个计数器

电影院:临界资源
买票:申请信号量 ————> 本质就是对公共资源的一种预定机制
票数:信号量的初始值

步骤:

  1. 申请信号量
  2. 访问临界资源
  3. 释放信号量

🍚对于整体使用的资源:

image-20241018113029550

🍗那我可不可以使用全局变量?

意思是,既然信号量是一个计数器,那我可不可以直接使用一个全局变量来表示计数器,想着可不可以完全替代信号量呢?

————不能!

  1. 全局变量不能被所有进程看到,因为进程之间具有独立性,而父子进程却很有可能发生写实拷贝。

  2. 不是原子的。

  • 什么是原子操作?

    **原子操作(Atomic Operation)**是指一个操作要么完整地执行,要么完全不执行。在多线程/多进程环境下,原子操作可以确保操作的完整性,不会被其他线程/进程打断。

而使用全局变量作为计数器时,增加和减少计数的操作通常需要多个步骤,比如:

  1. 读取全局变量的值
  2. 对值进行修改
  3. 将修改后的值写回全局变量

这三个步骤并不是一个原子操作。在多线程/进程环境下,如果两个线程/进程同时执行这三个步骤,就可能出现竞争条件(race condition),导致计数器的值不准确。

比如:

  • 进程A读取计数器值为10
  • 进程B也读取计数器值为10
  • 进程A将值加1写回为11
  • 进程B将值加1写回为11

此时,计数器的值应该是12,但实际只变成了11,出现了错误。

所以还得是信号量,不能是任何什么全局变量这种非原子的

  • 所以就得让多个进程看到一个信号量(计数器)

    那就说明这个信号量本质就是一个公共资源!

    既然你作为信号量,你的任务是保证其它临界资源的安全,那首先你得保证自己是安全的!

    有很多方法保证信号量自身是安全的,那些操作我们以后讲,不过现在我们可以就原子性来讲讲。

    image-20241018115034071

  • 信号量的核心操作 P(wait) 和 V(signal) 都是原子操作。

  • 即这些操作要么完全执行,要么完全不执行,中间不会被中断,再按照上面局列举的例子就能理解如何保护临界资源的。

OS是如何把共享内存、消息队列、信号量统一管理起来的?

先组织,再描述!

image-20241018122812480

struct kern_ipc_perm 是在 Linux 内核中用于管理进程间通信(IPC)对象的权限结构体。它是内核中 ipc_perm 的扩展版本,特意用于对共享内存、消息队列、信号量等 System V IPC 机制进行权限管理和控制。在用户空间中,ipc_perm 提供的是一个简化版的权限结构,而 kern_ipc_perm 则是内核用来管理这些权限的完整结构。

struct ipc_id_ary 是 Linux 内核中用于管理 System V IPC 对象(如共享内存、消息队列、信号量)的数据结构之一。它的主要作用是管理和跟踪所有的 IPC 资源,并存储这些 IPC 资源的标识符和相关信息。

IPC(进程间通信)资源在内核中通常通过索引和标识符(shmidmsqidsemid 等)进行管理。ipc_id_ary 是一个数组结构,用于保存 IPC 资源的 ID 和对应的数据结构,通常包括每种 IPC 对象类型(共享内存、消息队列、信号量)的标识符和状态信息。

你每创建一个共享内存或者消息队列,本质就是先进行一次struct kern_ipc_perm对象实例化,这里包含了该共享内存的key和序列号seq,而struct kern_ipc_perm每次的创建都会由struct ipc_id_ary里的柔性数组做管理,这里就是你每一次创建一个共享内存,我这里的下标就会加一,这也就是为什么你每次拿到shmid都会在上次的基础上加一,因此shmid本质就是struct ipd_id_ary里的柔性数组的下标,而每当你释放共享内存。

序列号的递增:共享内存段删除时,内核不会重新使用之前的序列号。相反,它会递增序列号,这样下次创建共享内存段时,即使使用相同的索引位置,生成的 shmid 也不同。

避免重复使用相同的 shmid:递增序列号的目的是为了防止系统意外地重新使用旧的 shmid。这可以防止进程在使用过期或无效的 shmid 时产生意外行为。

现在我们可以说完成了进程间通信的话题,管道是在内核中对缓冲区实现通信,命名管道则是对文件,共享内存则是对一个数组,不过是在用户层面上的。下一章我们将开启Linux信号。

http://www.dt0577.cn/news/14728.html

相关文章:

  • 深圳响应式网站建设企业网络推广的方法有哪些
  • 巴城镇建设网站关键词排名优化软件价格
  • 河北涿州住房和城乡建设厅网站媒体:北京不再公布疫情数据
  • 那个网站可教做课件好百度浏览器网址
  • seo网站建设百度官网首页登录
  • 网站开发超速云seo是干啥的
  • 漯河做网站xknt小程序推广的十种方式
  • 传媒公司营业执照怎么办理如何提高搜索引擎优化
  • 广州高端品牌网站建设哪个搜索引擎最好用
  • 湖北住房城乡建设厅网站seo网络优化招聘信息
  • 开个做网站公司百度app大全
  • 网站设计 原型图seo技术优化整站
  • 做网站的重要性软广告经典案例
  • 我有网站 怎么做淘宝推广的足球世界排名一览表
  • 网站建设职业规划东莞网络推广营销
  • wordpress如何在数据库中修改域名上海专业seo服务公司
  • dw动态网站怎么做搜索框营销型企业网站建设步骤
  • 权威网站设计搜索引擎优化实训心得
  • 大理公司网站建设信息流广告模板
  • 手机网站会员中心模板免费发布广告
  • 大连网站的公司乐云seo官网
  • 长沙营销型网站开发体球网足球世界杯
  • 德州网站收录大数据精准营销
  • 牡丹江网站制作百度一下网页打开
  • 网站建设 方案郑州网站关键词优化公司哪家好
  • qq网站登录网址济南头条新闻热点
  • java web网站开发模板网络营销平台排名
  • 用vs做asp新闻网站如何制作自己的网址
  • 做传销网站后果严重吗制作网站要花多少钱
  • 企业网站收费联合早报 即时消息