C/C++ 进程间通信system V IPC对象超详细讲解(系统性学习day9)

 

目录

前言

一、system V IPC对象图解

1.流程图解:

​编辑

2.查看linux内核中的ipc对象:

 二、消息队列

1.消息队列的原理

2.消息队列相关的API

2.1 获取或创建消息队列(msgget)

 实例代码如下:

2.2 发送消息到消息队列中

 实例代码如下:

2.3 从消息队列中获取消息  

实例代码如下: 

 2.4 消息队列相关的命令

 2.5 管理消息队列

 实例代码如下:

三、共享内存

1.概念

2.原理图解

3.相关的api函数

3.1 创建共享内存对象

 实例代码如下:

3.2 映射共享内存  

 3.3 取消映射

 实例代码reader.c如下:

 实例代码writer.c如下:

实例代码shm.h 如下:

 3.4 管理共享内存

实例代码如下: 

四、信号灯 (信号量)

1.概念

2.信号灯相关的api函数

2.1 创建或获取信号灯对象

实例代码如下:

2.2 实现P操作和V操作  

实例代码如下:

2.3 管理信号灯  

实例代码如下: 

总结


前言

System V IPC(Inter-Process Communication)对象是一种用于在不同进程之间进行通信的机制。它包括三种类型的对象:消息队列(Message Queue)、信号量(Semaphore)和共享内存(Shared Memory)。


一、system V IPC对象图解

1.流程图解:

e3b7f73d700f4fe085171956b7ac8851.png

2.查看linux内核中的ipc对象:

fbaf8bbd33cc44b59fc87277a69541ee.png

 

 二、消息队列

1.消息队列的原理

d8f9942acfe846f0a214a7fade16240d.png

 

2.消息队列相关的API

2.1 获取或创建消息队列(msgget)

头文件:

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

int msgget(key_t key, int msgflg);
//参数1  ----- key :
               动态获取key:  ftok()
                    #include <sys/types.h>
                    #include <sys/ipc.h>
                    key_t ftok(const char *pathname, int proj_id);
                    //参数1  ---- 工程目录
                    //参数2  ---- 工程编号
                    //返回值 ----- 成功,返回key值,失败:-1
               静态分配: IPC_PRIVATE
//参数2 ------ msgflg:如果消息队列不存在,需要给出创建的关键字,并设置权限 IPC_CREAT | 0666
//返回值 ----- 成功:消息队列的ID,失败:-1    

 实例代码如下:

int main(void)
{key_t key;int msg_id;//获取key值key = ftok("./",0xa);if(key < 0){perror("ftok");exit(1);}//创建或获取消息对象msg_id = msgget(key,IPC_CREAT|0666);if(msg_id < 0){perror("msgget");exit(1);}return 0;
}

2.2 发送消息到消息队列中

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
//参数1 ----- 消息队列的id
//参数2 -----  指向struct msgbuf结构体的指针,该结构体需要自己定义,如下:
                struct msgbuf {
                   long mtype;       /* message type, must be > 0 消息类型*/
                   char mtext[1];    /* message data  消息正文*/
                };
//参数3 ---- 要发送的消息的长度 
//参数4 ---- msgflg值如下:
            IPC_NOWAIT  消息没有发送完成函数也会立即返回。
            0:直到发送完成函数才返回
//返回值 --- 成功:0,失败:-1

 实例代码如下:

int main(void)
{key_t key;int msg_id;//获取key值key = ftok("./",0xa);if(key < 0){perror("ftok");exit(1);}//创建或获取消息对象msg_id = msgget(key,IPC_CREAT|0666);if(msg_id < 0){perror("msgget");exit(1);}//向消息队列中发送消息while(1){bzero(&buf,sizeof(buf));printf("请输入消息的类型:");scanf("%ld",&buf.mtype);printf("请输入消息:");while(getchar() != '\n');   //清空输入缓冲区fgets(buf.mtext,sizeof(buf.mtext),stdin);buf.mtext[strlen(buf.mtext)-1] = '\0';if(msgsnd(msg_id,&buf,strlen(buf.mtext),0) < 0){perror("msgsnd");exit(1);}}return 0;
}

2.3 从消息队列中获取消息  

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
//参数1 ----- 消息队列的id
//参数2 -----  指向struct msgbuf结构体的指针,该结构体需要自己定义,如下:
                struct msgbuf {
                   long mtype;       /* message type, must be > 0 消息类型*/
                   char mtext[1];    /* message data  消息正文*/
                };
//参数3 ----  mtext的长度
//参数4 ----  msgtyp:要接收的消息类型
             msgtyp > 0 ,表示接收指定类型的消息 
             msgtyp = 0 ,按先后顺序依次接收不同类型消息
             msgtyp < 0 ,优先接收消息类型不大于|msgtyp|的最小类型的消息
//参数5 ---- msgflg值如下:
            IPC_NOWAIT  消息没有发送完成函数也会立即返回。
            0:直到发送完成函数才返回
//返回值 --- 成功:0,失败:-1

实例代码如下: 

int main(void)
{key_t key;int msg_id;//获取key值key = ftok("./",0xa);if(key < 0){perror("ftok");exit(1);}//创建或获取消息对象msg_id = msgget(key,IPC_CREAT|0666);if(msg_id < 0){perror("msgget");exit(1);}//从消息队列中获取消息while(1){bzero(&buf,sizeof(buf));printf("请输入消息的类型:");scanf("%ld",&buf.mtype);if(msgrcv(msg_id,&buf,sizeof(buf.mtext),buf.mtype,0) < 0){perror("msgsnd");exit(1);}printf("msg:%s\n",buf.mtext);}return 0;
}

 2.4 消息队列相关的命令

peter@ubuntu:~/2308/proc/day04_code$ ipcs -q

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages
0x0a010356 0          peter      666        61           5

peter@ubuntu:~/2308/proc/day04_code$ ipcrm -q 0
peter@ubuntu:~/2308/proc/day04_code$ ipcs -q

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages

 2.5 管理消息队列

int msgctl(int msqid, int cmd, struct msqid_ds *buf);
 //参数1 ---- 消息队列ID
 //参数2 ---- 功能码:
                 IPC_STAT:读取消息队列的属性,并将其保存在buf指向的缓冲区中。
                IPC_SET:设置消息队列的属性。这个值取自buf参数。
                IPC_RMID:从系统中删除消息队列。    
 //参数3 ----struct msqid_ds 结构体指针
                 struct msqid_ds {
                       struct ipc_perm msg_perm;     /* Ownership and permissions */
                       time_t          msg_stime;    /* Time of last msgsnd(2) */
                       time_t          msg_rtime;    /* Time of last msgrcv(2) */
                       time_t          msg_ctime;    /* Time of last change */
                       unsigned long   __msg_cbytes; /* Current number of bytes in
                                                        queue (nonstandard) */
                       msgqnum_t       msg_qnum;     /* Current number of messages
                                                        in queue */
                       msglen_t        msg_qbytes;   /* Maximum number of bytes
                                                        allowed in queue */
                       pid_t           msg_lspid;    /* PID of last msgsnd(2) */
                       pid_t           msg_lrpid;    /* PID of last msgrcv(2) */
                   };

 实例代码如下:

int main(int argc,char **argv)
{int msg_id;msg_id = atoi(argv[1]);if(msgctl(msg_id,IPC_RMID,NULL) < 0){perror("msgget");exit(1);}return 0;
}

三、共享内存

1.概念

共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝

为了在多个进程间交换信息,内核专门留出了一块内存区,可以由需要访问的进程将其映射到自己的私有地址空间

进程就可以直接读写这一内存区而不需要进行数据的拷贝,从而大大提高的效率。

由于多个进程共享一段内存,因此也需要依靠某种同步机制,如互斥锁和信号量等 

2.原理图解

 d3ea3585b84f4dd1a960bd7045694f9f.png

 

3.相关的api函数

3.1 创建共享内存对象

头文件:

#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
//参数1 ---- 动态获取key:  ftok()
                    #include <sys/types.h>
                    #include <sys/ipc.h>
                    key_t ftok(const char *pathname, int proj_id);
                    //参数1  ---- 工程目录
                    //参数2  ---- 工程编号
                    //返回值 ----- 成功,返回key值,失败:-1
               静态分配: IPC_PRIVATE
//参数2 ---- 要创建或获取的共享内存的大小
//参数3 ---- 权限:IPC_CREAT | 0666
//返回值 ---- 成功:共享内存ID,失败:-1

 实例代码如下:

int main(void)
{key_t key;int shm_id;//获取key值key = ftok("./",0xa);if(key < 0){perror("ftok");exit(1);}//创建或获取共享内存对象shm_id = shmget(key,SHM_SIZE, IPC_CREAT|0666);if(shm_id < 0){perror("shmget");exit(1);}return 0;
}

3.2 映射共享内存  

void *shmat(int shmid, const void *shmaddr, int shmflg);
//参数1 ---- 共享内存ID
//参数2 ---- 指定进程虚拟空间的映射的起始地址,一般为NULL:让系统分配一个起始地址
//参数3 ---- 访问权限:SHM_RDONLY:共享内存只读
                    默认0:共享内存可读写
//返回值 --- 成功:映射的虚拟空间地址,失败:-1

 3.3 取消映射

int shmdt(const void *shmaddr);
//参数 ----映射的虚拟空间的起始地址
//返回值 ----成功:0,失败:-1

 实例代码reader.c如下:

#include "shm.h"int main(void)
{key_t key;int shm_id;char *buf;//获取key值key = ftok("./",0xa);if(key < 0){perror("ftok");exit(1);}//创建或获取共享内存对象shm_id = shmget(key,SHM_SIZE, IPC_CREAT|0666);if(shm_id < 0){perror("shmget");exit(1);}//将共享内存映射到进程的虚拟空间中buf = (char*)shmat(shm_id,NULL,0);if(buf < 0){perror("shmat");exit(1);}//打印共享内存中的数据while(1){printf("%s",buf);sleep(1);}//解除映射if(shmdt(buf) < 0){perror("shmdt");exit(1);}return 0;
}

 实例代码writer.c如下:

#include "shm.h"int main(void)
{key_t key;int shm_id;char *buf;//获取key值key = ftok("./",0xa);if(key < 0){perror("ftok");exit(1);}//创建或获取共享内存对象shm_id = shmget(key,SHM_SIZE, IPC_CREAT|0666);if(shm_id < 0){perror("shmget");exit(1);}//将共享内存映射到进程的虚拟空间中buf = (char*)shmat(shm_id,NULL,0);if(buf < 0){perror("shmat");exit(1);}//向共享内存写数据while(1){printf("请输入字符串:");fgets(buf,SHM_SIZE,stdin);}//解除映射if(shmdt(buf) < 0){perror("shmdt");exit(1);}return 0;
}

实例代码shm.h 如下:

#ifndef __SHM_H__
#define __SHM_H__#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>#define SHM_SIZE  1024#endif

 3.4 管理共享内存

int shmctl(int shmid, int cmd, struct shmid_ds *buf);
//参数1 ---- 共享内存的ID
//参数2 ---- 功能码:
            IPC_STAT  (获取对象属性)
            IPC_SET (设置对象属性)
            IPC_RMID (删除对象)    
//参数3 ----struct shmid_ds 结构体指针
            struct shmid_ds {
               struct ipc_perm shm_perm;    /* Ownership and permissions */
               size_t          shm_segsz;   /* Size of segment (bytes) */
               time_t          shm_atime;   /* Last attach time */
               time_t          shm_dtime;   /* Last detach time */
               time_t          shm_ctime;   /* Last change time */
               pid_t           shm_cpid;    /* PID of creator */
               pid_t           shm_lpid;    /* PID of last shmat(2)/shmdt(2) */
               shmatt_t        shm_nattch;  /* No. of current attaches */
               ...
           };

实例代码如下: 

int main(int argc,char **argv)
{int shm_id;shm_id = atoi(argv[1]);if(shmctl(shm_id,IPC_RMID,NULL) < 0){perror("shmget");exit(1);}return 0;
}

四、信号灯 (信号量)

1.概念

信号灯(semaphore),也叫信号量。它是不同进程间或一个给定进程内部不同线程间同步的机制。
信号灯种类:
    posix有名信号灯
    posix基于内存的信号灯(无名信号灯)
    System V信号灯(IPC对象)

1》 二值信号灯:用于表示资源是否可用
    值为0或1。与互斥锁类似,资源可用时值为1,不可用时值为0。

2》 计数信号灯:用于表示资源的数量
    值在0到n之间。用来统计资源,其值代表可用资源数

3》 等待操作,也称为P操作
    是等待信号灯的值变为大于0,然后将其减1;
4》 释放操作,也称为V操作
     用来唤醒等待资源的进程或者线程

5》System V的信号灯是一个或者多个信号灯的一个集合。其中的每一个都是单独的计数信号灯。而Posix信号灯指的是单个计数信号灯
 

2.信号灯相关的api函数

2.1 创建或获取信号灯对象

头文件:

 #include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key_t key, int nsems, int semflg);
//参数1 ---- 动态获取key:  ftok()
                    #include <sys/types.h>
                    #include <sys/ipc.h>
                    key_t ftok(const char *pathname, int proj_id);
                    //参数1  ---- 工程目录
                    //参数2  ---- 工程编号
                    //返回值 ----- 成功,返回key值,失败:-1
               静态分配: IPC_PRIVATE
//参数2 ---- 集合中信号灯的个数
//参数3 ---- 访问权限:IPC_CREAT | 0666
//返回值 ---- 成功:信号灯对象ID,失败:-1

实例代码如下:

int main(void)
{key_t key;int sem_id;//获取key值key = ftok("./",0xa);if(key < 0){perror("ftok");exit(1);}//创建或获取共享内存对象sem_id = semget(key,1, IPC_CREAT|0666);if(sem_id < 0){perror("semget");exit(1);}return 0;
}

2.2 实现P操作和V操作  

int semop(int semid, struct sembuf *sops, size_t nsops);
//参数1 ----- 信号灯对象的ID
//参数2 ----- 结构体指针
                struct sembuf {
                   short  sem_num;  //  要操作的信号灯的编号
                   short  sem_op;   //    0 :  等待,直到信号灯的值变成0
                                               //   1  :  释放资源,V操作
                                               //   -1 :  分配资源,P操作                   
                   short  sem_flg; // 0,  IPC_NOWAIT,  SEM_UNDO
                };

//参数3 -----nops:  要操作的信号灯的个数
//返回值 ---- 成功:0,失败:-1

实例代码如下:

//1》实现P操作void sem_p(int sem_id,int index){struct sembuf buf = {index,-1,0};if(semop(sem_id,&buf,1) < 0){perror("semop");exit(1);}}
//2》实现v操作void sem_v(int sem_id,int index){struct sembuf buf = {index,1,0};if(semop(sem_id,&buf,1) < 0){perror("semop");exit(1);}}

2.3 管理信号灯  

int semctl(int semid, int semnum, int cmd, ...);
//参数1 ---- 信号灯对象ID
//参数2 ---- 集合中信号灯的编号
//参数3 ---- 功能码:
            IPC_STAT  ----获取信号灯对象属性
            IPC_SET   ----设置信号灯对象属性
            IPC_RMID  ----从内核中删除信号灯对象
            SETALL      ----设置集合中所有信号灯的值
            SETVAL    ----设置集合中编号为semnum的信号灯的值
//参数4 ---- 联合体变量,类型如下:
            union semun {
               int              val;    /* Value for SETVAL */
               struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
               unsigned short  *array;  /* Array for GETALL, SETALL */
               struct seminfo  *__buf;  /* Buffer for IPC_INFO
                                           (Linux-specific) */
           };
//返回值 -----成功:0,失败:-1

实例代码如下: 

//初始化指定的信号灯
void sem_init(int sem_id,int semnum,int value)
{union semun su;su.val = value;if(semctl(sem_id,semnum,SETVAL,su) < 0){perror("semctl");exit(1);}
}
//初始化所有信号灯
void sem_init_all(int sem_id,unsigned short vals[])
{union semun su;su.array = vals;if(semctl(sem_id,0,SETALL,su) < 0){perror("semctl");exit(1);}
}

 


总结

        本篇文章针对进程间通信system V IPC对象进行详细讲解,希望能够帮到大家!

        以后还会给大家展现更多关于嵌入式和C语言的其他重要的基础知识,感谢大家支持懒大王!

       希望这篇博客能给各位朋友们带来帮助,最后懒大王请来过的朋友们留下你们宝贵的三连以及关注,感谢你们!

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/151526.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

单元测试该怎么写

单元测试对于开发人员来说很熟悉&#xff0c;各种语言都提供了单元测试的框架&#xff0c;用于自动化执行单元测试并生成测试报告。它通常提供了一组API和工具&#xff0c;使开发人员能够编写和运行测试用例&#xff0c;比较预期行为和实际行为之间的差异&#xff0c;并准确地识…

多线程锁-synchronized字节码分析

从字节码角度分析synchronized实现 javap -c(v附加信息) ***.class 文件反编译 synchronized同步代码块 >>>实现使用的是monitorenter和monitorexit指令 synchronized普通同步方法 >>>调用指令将会检查方法的ACC_SYNCHRONIZED访问标志是否被设置&#xf…

【数据结构-二叉树 九】【树的子结构】:树的子结构

废话不多说&#xff0c;喊一句号子鼓励自己&#xff1a;程序员永不失业&#xff0c;程序员走向架构&#xff01;本篇Blog的主题是【子结构】&#xff0c;使用【二叉树】这个基本的数据结构来实现&#xff0c;这个高频题的站点是&#xff1a;CodeTop&#xff0c;筛选条件为&…

不同数据类型在单片机内存中占多少字节?

文章目录 前言一、不同编译器二、C51* 指针型 三、sizeof结构体联合体 前言 在C语言中&#xff0c;数据类型指的是用于声明不同类型的变量或者函数的一个广泛的系统。变量的类型决定了变量存储占用的空间 一、不同编译器 类型16位编译器大小32位编译器大小64位编译器大小char…

Kafka 简介之(学习之路)

正文 一、简介 1.1 概述 Kafka是最初由Linkedin公司开发&#xff0c;是一个分布式、分区的、多副本的、多订阅者&#xff0c;基于zookeeper协调的分布式日志系统&#xff08;也可以当做MQ系统&#xff09;&#xff0c;常见可以用于web/nginx日志、访问日志&#xff0c;消息服务…

软件设计原则 1小时系列 (C++版)

文章目录 前言基本概念 Design Principles⭐单一职责原则(SRP) Single Responsibility PrincipleCode ⭐里氏替换原则(LSP) Liskov Substitution PrincipleCode ⭐开闭原则(OCP) Open Closed PrincipleCode ⭐依赖倒置原则(DIP) Dependency Inversion PrincipleCode ⭐接口隔离…

【抢先体验】开通使用 ChatGPT 语音版功能保姆级教程

大家好&#xff0c;我是苍何&#xff0c;一个土木转码的非典型程序员&#xff0c;也是一名技术管理者&#xff0c;同时也是 AI 应用的探索者。今天在视频号上看到和 ChatGPT 语音对话的视频&#xff0c;其声音的真实感太让人震撼了&#xff0c;于是也想去抢先体验一下 ChatGPT …

Centos7安装MongoDB7.xxNoSQL数据库|设置开机启动(骨灰级+保姆级)

一: mongodb下载 MongoDB 社区免费下载版 MongoDB社区下载版 [rootwww tools]# wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-7.1.0-rc4.tgz 二: 解压到指定目录 [rootwww tools]# mkdir -p /usr/local/mongodb [rootwww tools]# tar -zxvf mongodb-…

选择适合普通公司的项目管理软件

不管是打工人还是学生党都适合使用Zoho Projects项目管理软件。利用项目概览功能&#xff0c;将整体项目尽收眼底&#xff0c;作为项目管理者&#xff0c;项目日程、进度都可见&#xff0c;Zoho Projects项目管理APP助推项目每一环节的进展&#xff0c;更便于管理者设计项目的下…

ThingsBoard如何自定义tcp-transport

1、概述 很久没有更新了,一直忙于其他的事情,最近去搞了一个在ThingsBoard中自定义一个tcp-transport,用于连接使用tcp长连接的设备,目前使用tcp和mqtt协议连接服务端的设备还是很多,ThingsBoard的PE版提供了Integration是可以实现tcp的接入,但是CE版是没有提供接入tcp长…

【MySQL】基本查询(二)

文章目录 一. 结果排序二. 筛选分页结果三. Update四. Delete五. 截断表六. 插入查询结果结束语 操作如下表 //创建表结构 mysql> create table exam_result(-> id int unsigned primary key auto_increment,-> name varchar(20) not null comment 同学姓名,-> chi…

IO 之 操作properties属性文件

propreties文件&#xff1a; properties文件是一种用于存储配置信息的文本文件&#xff0c;通常以“.properties”为文件扩展名。它是一种简单的键值对格式&#xff0c;用于保存应用程序的配置参数。 在properties文件中&#xff0c;每一行都包含一个键值对&#xff0c;键和值…

HTTPS工作过程,国家为什么让http为什么要换成https,Tomcat在MAC M1电脑如何安装,Tomcat的详细介绍

目录 引言 一、HTTPS工作过程 二、Tomcat 在访达中找到下载好的Tomcat文件夹&#xff08;这个要求按顺序&#xff09; zsh: permission denied TOMCAT的各部分含义&#xff1a; 引言 在密码中一般是&#xff1a;明文密钥->密文&#xff08;加密&#xff09; &#xff…

Spring源码解析——IOC属性填充

正文 doCreateBean() 主要用于完成 bean 的创建和初始化工作&#xff0c;我们可以将其分为四个过程&#xff1a; 最全面的Java面试网站 createBeanInstance() 实例化 beanpopulateBean() 属性填充循环依赖的处理initializeBean() 初始化 bean 第一个过程实例化 bean在前面一篇…

复旦大学EMBA:揭秘科创企业,领略未来战略!

智能制造&#xff0c;国之重器。作为制造强国建设的主攻方向&#xff0c;智能制造的发展水平关系到我国未来制造业在全球的地位与影响力。发展智能制造&#xff0c;是加快建设现代化产业体系的重要手段&#xff0c;提升供给体系适配性的有力抓手&#xff0c;也是建设数字中国的…

【C++设计模式之状态模式:行为型】分析及示例

简介 状态模式&#xff08;State Pattern&#xff09;是一种行为型设计模式&#xff0c;它允许对象在内部状态改变时改变其行为&#xff0c;看起来就像是改变了其类。状态模式将对象的状态封装成不同的类&#xff0c;并使得对象在不同状态下有不同的行为。 描述 状态模式通过…

Android用户登录与数据存储:从权限请求到内外部存储的完整实践【完整实践步骤、外部存储、内部存储】

步骤 1: 登录页面布局 在 MainActivity 中实现用户登录功能&#xff0c;首先创建一个布局文件 activity_main.xml 包含用户名和密码的输入字段以及登录按钮。 <!-- activity_main.xml --> <LinearLayoutxmlns:android"http://schemas.android.com/apk/res/andr…

Qt之实现圆形进度条

在Qt自带的控件中&#xff0c;只有垂直进度条、水平进度条两种。 在平时做页面开发时&#xff0c;有些时候会用到圆形进度条&#xff0c;比如说&#xff1a;下载某个文件的下载进度。 展示效果&#xff0c;如下图所示&#xff1a; 实现这个功能主要由以下几个重点&#xff1a…

记录vue开发实例

封装的表格组件 <template><div><div style"width: 100%" v-if"showList"><el-table v-loading.lock"loading" :data"dataList":header-cell-style"{background: #F2FCFE,fontSize: 14px,color: #50606D}&…

因为在此系统上禁止运行脚本

问题&#xff1a; 解决办法&#xff1a; vue项目搭建中"因为在此系统上禁止运行脚本"报错&#xff0c;解决方法 - 你的剧本 - 博客园 (cnblogs.com)