IO进程线程(IPC通讯)

目录

一、IPC通讯机制

1)传统的通讯机制:

2)systemV 的通讯机制:

3)跨主机的通讯机制:

1、无名管道

1)无名管道的概念

2)无名管道的函数

3)无名管道通讯(亲缘进程)

2、有名管道

1)有名管道的概念

2)有名管道的函数

 3)有名管道通讯(无亲缘进程)

3、信号 

1)信号的概念

2)了解信号

3)信号的处理方式

4)signal(模拟中断)

练习:捕获信号 2)SIGHUP也就是ctrl c

 练习:捕获信号 13)SIGPIPE 管道破裂

练习:使用signal回收僵尸进程

5)kill(给指定进程发送指定信号)

 6)raise(给自己发送信号)

7)alarm(秒级定时器)

 4、消息队列

1)消息队列原理

2)消息队列的指令(ipcs)

3)ftok(创建密钥)

 4)stat(查看文件路径及属性)

5)msgget(创建消息队列)

6)msgsnd(发送信息)

7)msgrcv(接收信息)

8)msgctl(删除、获取、修改队列信息)


一、IPC通讯机制

IPC:是指(inter process communction)进程间通讯机制

进程之间通讯可以通过文件实现,但是进程之间不清楚是什么时候开始通讯,因此实时操作性差。

由此 引出 IPC 通讯机制,他是通过内核空间共享实现,多个用户空间独立的进程之间通讯

1)传统的通讯机制:

        1. 无名管道文件 pipo

        2. 有名管道文件 fifo

        3. 信号 signal

2)systemV 的通讯机制:

        1. 消息队列 messge queue

        2. 共享内存 shard memory

        3. 信号灯集 semphore

3)跨主机的通讯机制:

        嵌套字 socket

1、无名管道

1)无名管道的概念

1. 无名管道本质上是一个文件(管道文件 p ),但是存储在内核中,普通文件存储在硬盘上

2. 管道文件是特殊文件,只可以使用文件IO函数操作(open、write、read、close),lseek不允许使用

3. 管道需要满足队列的思想(先进先出),管道中的数据是一次性的,读取数据后删除数据

4. 管道属于半双工通讯机制

5. 当管道的读写端同时关闭,此时管道的内存自动释放

6. 管道的大小位:64K

7. 无名管道只适用于有亲缘关系的进程间的通讯

8. 如果打开写端,关闭读端,写入字符会发生管道破裂(SIGPIPE)

2)无名管道的函数

格式:#include <unistd.h>int pipe(int pipefd[2]);
功能:创建无名管道
参数:int pipefd[2]:存储管道两端的文件描述符pipefd[0]:读端的文件描述符pipefd[1]:写端的文件描述符
返回值:成功返回0,失败返回-1,跟新errno

3)无名管道通讯(亲缘进程)

#include <25051head.h>
int main(int argc, const char *argv[]){//创建管道//pipefd[0]:读  pipefd[1]:写int pipefd[2];if(-1==pipe(pipefd)){ERRLOG("pipe error");}//无名管道用于存在亲缘关系之间的进程通信,所以需要创建父子进程pid_t pid=fork();if(pid==-1){ERRLOG("fork error");}else if(0==pid) //子进程{close(pipefd[1]);//读char buf[128]="";while(1){memset(buf,0,sizeof(buf));ssize_t res=read(pipefd[0],buf,sizeof(buf)-1);if(res==0){printf("读取到文件的结尾..\n");break;}else if(res==-1){ERRLOG("read error");}if(strcmp(buf,"quit")==0){printf("子进程退出..\n");break;}//读取成功printf("buf=[%s]\n",buf);}close(pipefd[0]);}else if(pid>0) //父进程{close(pipefd[0]);//写while(1){                                  char buf[128]="";fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1]='\0';//把buf写入到管道文件中write(pipefd[1],buf,strlen(buf));if(strcmp(buf,"quit")==0){printf("父进程退出..\n");break;}}close(pipefd[1]);}return 0;
}

2、有名管道

1)有名管道的概念

有名管道和无名管道特点一致,只有一点不同:有名管道可用于无亲缘关系的进程间通讯

2)有名管道的函数

格式:#include <sys/types.h>#include <sys/stat.h>int mkfifo(const char *pathname, mode_t mode);功能:创建有名管道
参数:const char *pathname:创建有名管道的文件名以及路径mode_t mode:有名管道文件的权限 0664 0777
返回值:成功返回0,失败返回-1.跟新errno指令:mkfifo 路径及文件名

 3)有名管道通讯(无亲缘进程)

3、信号 

1)信号的概念

信号是软件层对中断的一种模拟

信号是异步通讯模式

异步是指任务和任务之间没有联系,按照CPU的时间片轮询机制访问

2)了解信号

信号可以通过指令 kill - l 查看

1  ~ 31:标准信号,当多次触发同一信号,内核只处理一次

34~ 64:实时信号,当多次触发同一信号是,会把信号存储到队列中,按照队列思想,逐个处理

编号

信号名

含义

快捷方式/触发方式

1

SIGHUP

终端挂断(如SSH连接断开、守护进程重载配置)

kill -1

或系统事件触发

2

SIGINT

终端中断请求(用户主动终止进程)

ctrl c

3

SIGQUIT

终端退出请求(类似SIGINT,生成核心转储用于调试)

Ctrl+\

4

SIGILL

非法指令(执行无效的CPU指令)

程序错误或硬件异常触发

5

SIGTRAP

断点陷阱(调试器捕获断点或单步执行)

调试器触发

6

SIGABRT

程序异常终止(由abort()函数触发)

assert()失败或

abort()调用

7

SIGBUS

总线错误(非法内存访问,如未对齐的内存操作)

硬件或内存错误触发

8

SIGFPE

浮点异常(如除以零、溢出)

算术运算错误触发

9

SIGKILL

强制终止进程(不可捕获或忽略)

kill -9

10

SIGUSR1

用户自定义信号(用途由程序定义,如重开日志)

kill -10

11

SIGSEGV

段错误(非法内存访问,如空指针解引用)

内存访问错误触发

12

SIGUSR2

用户自定义信号2(用途由程序定义)

kill -12

13

SIGPIPE

管道破裂(向无读端的管道写数据)

管道操作错误触发

14

SIGALRM

定时器超时(由alarm()或setitimer()设置)

定时器到期触发

15

SIGTERM

终止请求(允许程序优雅退出,默认kill命令发送的信号)

kill -15  或  kill

(无参数)

16

SIGSTKFLT

协处理器栈错误(少见,部分系统未实现)

硬件协处理器错误触发

17

SIGCHLD

子进程状态变更(子进程终止或暂停)

子进程事件触发

18

SIGCONT

继续执行进程(恢复被暂停的进程)

fg

命令或

kill -18

19

SIGSTOP

暂停进程(不可捕获或忽略)

Ctrl+Z

(部分系统行为)

20

SIGTSTP

终端暂停请求(后台进程尝试终端输入/输出)

Ctrl+Z

23

SIGURG

紧急数据到达(如TCP带外数据)

网络数据包触发

24

SIGXCPU

超出CPU时间限制(资源限制触发)

setrlimit()

设置超限触发

25

SIGXFSZ

超出文件大小限制(如写入超过 ulimit 限制的文件)

文件操作超限触发

26

SIGVTALRM

虚拟定时器超时(基于进程的虚拟时间)

setitimer(ITIMER_VIRTUAL)

触发

27

SIGPROF

性能分析定时器超时(统计CPU时间)

setitimer(ITIMER_PROF)

触发

28

SIGWINCH

终端窗口大小变化(如调整终端窗口)

终端尺寸变更事件触发

29

SIGIO

异步I/O事件(文件描述符准备就绪)

I/O事件触发(需配置fcntl())

30

SIGPWR

电源故障(系统关机前通知进程)

UPS或电源管理事件触发

31

SIGSYS

无效系统调用(执行不存在或参数错误的系统调用)

非法系统调用触发

34

SIGRTMIN

实时信号起始编号(自定义用途,范围:

SIGRTMIN ~ SIGRTMAX,通常34~64)

kill -34

或更高编号

3)信号的处理方式

信号屏蔽:在执行信号处理时,连续触发同一个信号,该信号只处理一次,这个行为我们称之为信号屏蔽,但是可以触发其他信号。

1. 执行默认操作:当触发信号时,执行默认的信号处理函数

2. 忽略信号:当触发信号时,忽略该信号不做处理

3. 捕获信号:当触发信号时,执行我们想让他执行的函数

4)signal(模拟中断)

格式:#include <signal.h>typedef void (*sighandler_t)(int);sighandler_t signal(int signum, sighandler_t handler);功能:信号处理,接收到指定信号,并选择处理方式(执行默认函数,忽略,捕获)
参数:int signum:指定信号,接收到该信号后,执行操作(可以填信号编号,也可以填信号(大写字母))sighandler_t handler: 有以下指定参数SIG_IGN: 忽略信号SIG_DFL: 执行默认操作填函数名(函数首地址): 触发执行该函数注意:9)SIGKILL 和 19)SIGSTOP 不允许捕获和忽略返回值:成功返回上一个信号处理,失败返回SIG_ERR 更新 errno
练习:捕获信号 2)SIGHUP也就是ctrl c

 练习:捕获信号 13)SIGPIPE 管道破裂

练习:使用signal回收僵尸进程

5)kill(给指定进程发送指定信号)

格式:#include <signal.h>int kill(pid_t pid, int sig);功能:发送信号给进程或者进程组
参数:pid_t pid:>0: 把信号发送给进程等于pid的进程=0:把信号发送给当前进程组下的所有有权发送的进程=-1:把信号发送给系统的所有进程,除了没有权限发送的init进程<0:但不是-1. 先取绝对值,进程组id,把信号发送给改进程组下有权发送的进程int sig:信号的编号 或者 宏0:会做错误检测,不发送信号
返回值:成功返回0,失败返回-1.跟新errno

 6)raise(给自己发送信号)

格式:#include <signal.h>int raise(int sig);功能:给调用者进程发送信号(自杀)
参数:int sig表示发送的信号编号 或在宏
返回值:成功返回0,失败返回非0

7)alarm(秒级定时器)

格式:#include <unistd.h>unsigned int alarm(unsigned int seconds);完全等价于:alarm--->kill(getpid(),14)   14) SIGALRM
功能:发送一个时钟信号
参数:unsigned int seconds:几秒闹钟响
返回值:返回上一次闹钟没有触发的剩余秒数,如果没有则返回0

 可以将alarm放在执行函数内,重复触发alarm。

 4、消息队列

1)消息队列原理

消息队列在内核中申请一片空间,把信息打包成结点存储在内核缓冲区中,进程通过访问内核缓冲区中结点实现通讯

1. 把数据打包成结点(数据类型、数据内容)

2. 需满足队列思想(先进先出),即使按类型读取数据,也要满足队列思想

3. 在读取消息队列的数据后,数据默认会删除

4. 消息队列属于全双工通讯机制

5. 消息队列不会随着进程的结束而结束,需要手动删除 或者 电脑重启 

2)消息队列的指令(ipcs)

ipcs            同时查看消息队列、共享内存段、信号量数组
ipcs -q         只查看消息队列
ipcs -q msgid   删除消息队列

3)ftok(创建密钥)

格式:#include <sys/types.h>#include <sys/ipc.h>key_t ftok(const char *pathname, int proj_id);功能:把pathname 和proj_id转换为秘钥的,被msgget shmget semget使用
参数:const char *pathname:路径以及文件名 (随便但是需要存在)int proj_id:可以写整数,字符(随便)
返回值:成功返回秘钥,失败返回-1,跟新errno,注意秘钥和stat有关     key=proj_id(低8位)+设备号(低8位)+inode(低16位)

 4)stat(查看文件路径及属性)

  #include <sys/types.h>#include <sys/stat.h>#include <unistd.h>int stat(const char *pathname, struct stat *statbuf);int lstat(int fd, struct stat *statbuf);
功能:stat查看文件以及路径的属性的,stat不可以查看连接文件,lstat函数可以查看连接文件
参数:const char *pathname:查看的文件以及路径struct stat *statbuf:该结构体指针重中存储 执行文件的属性信息struct stat {dev_t     st_dev;         /* 设备号 */ino_t     st_ino;         /* inode号 */mode_t    st_mode;        /* 文件类型和权限 */nlink_t   st_nlink;       /* 硬连接数 */uid_t     st_uid;         /* 用户id */gid_t     st_gid;         /* 组id */dev_t     st_rdev;        /* 设备id*/off_t     st_size;        /* 总字节大小 */blksize_t st_blksize;     /* Block size for filesystem I/O */blkcnt_t  st_blocks;      /* Number of 512B blocks allocated *//* Since Linux 2.6, the kernel supports nanosecondprecision for the following timestamp fields.For the details before Linux 2.6, see NOTES. */struct timespec st_atim;  /* 最后一次访问的时间 */struct timespec st_mtim;  /* 最后一次修改的事件 */struct timespec st_ctim;  /* 最后一次状态值修改的之间 */#define st_atime st_atim.tv_sec      /* Backward compatibility */#define st_mtime st_mtim.tv_sec#define st_ctime st_ctim.tv_sec};

5)msgget(创建消息队列)

格式:#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>int msgget(key_t key, int msgflg);功能:创建消息队列的
参数:
key_t key:秘钥,ftok函数的返回值
int msgflg:实际怎么IPC_CREAT | 0664 或者 IPC_CREAT|IPC_EXCL|0664IPC_CREAT:如果消息队列不存在,则创建消息队列,存在不会报错IPC_CREAT|IPC_EXCL:如果细队列存在则报错EEXIST,不存在则创建
返回值:成功返回消息队列id,失败返回-1,。跟新errno         

6)msgsnd(发送信息)

格式:    #include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);功能:发送消息包的
参数:int msqid:消息队列idconst void *msgp: 发送的消息包,例如下面的结构体struct msgbuf {long mtype;       /* 消息的类型, 必须> 0 */char mtext[1];    /* 消息的内容 */};//发送一个字符串struct A {long a;       /* 消息的类型, 必须> 0 */char str[128];    /* 消息的内容 */};//发送一个整数struct B {long b;       /* 消息的类型, 必须> 0 */int num;    /* 消息的内容 */};//发送一个学生的信息struct V {long c;       /* 消息的类型, 必须> 0 */char name[128];    /* 消息的内容 */int age;float high;};size_t msgsz:消息内容的细节大小 sizeof(struct msgbuf)-sizeof(long)int msgflg :0:阻塞 当消息满后则阻塞IPC_NOWAIT:非阻塞函数,当消息队列满不会阻塞,但是报错EAGAIN
返回值:成功返回0,失败返回-1         

7)msgrcv(接收信息)

格式:#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
功能:接收消息队列的数据包
参数:int msqid:消息队列idconst void *msgp: 发送的消息包,例如下面的结构体struct msgbuf {long mtype;       /* 消息的类型, 必须> 0 */char mtext[1];    /* 消息的内容 */};//发送一个字符串struct A {long a;       /* 消息的类型, 必须> 0 */char str[128];    /* 消息的内容 */};//发送一个整数struct B {long b;       /* 消息的类型, 必须> 0 */int num;    /* 消息的内容 */};//发送一个学生的信息struct V {long c;       /* 消息的类型, 必须> 0 */char name[128];    /* 消息的内容 */int age;float high;};size_t msgsz:消息内容的细节大小 sizeof(struct msgbuf)-sizeof(long)long msgtyp:指定消息队列的类型=0:读取消息队列的第一条信息        >0: 读取类型等于msgtyp的第一条信息如果msgflag指定MSG_EXCEPT,读取不等于msgtype的第一条信息<0:读取小于等于msgtype绝对值的第一条信息int msgflg :0:阻塞 当消息满后则阻塞IPC_NOWAIT:非阻塞函数,当消息队列满不会阻塞,但是报错EAGAIN返回值:成功返回消息内容的字节大小,失败返回-1 ,跟新errno1:aaa 2:bbb 6:cccc 2:dddd 4:eeee 3:ffff
msgtyp=0
msgrcv(msqid, &buf, sizeof(buf)-sizeof(long), 0,0);    //aaa
msgrcv(msqid, &buf, sizeof(buf)-sizeof(long), 0,0);     //bbb    
msgrcv(msqid, &buf, sizeof(buf)-sizeof(long), 0,0);     //ccc
msgrcv(msqid, &buf, sizeof(buf)-sizeof(long), 0,0);     //ddd   
msgtype>0
msgrcv(msqid, &buf, sizeof(buf)-sizeof(long), 2,0);//bbb
msgrcv(msqid, &buf, sizeof(buf)-sizeof(long), 2,0);//dddd
msgrcv(msqid, &buf, sizeof(buf)-sizeof(long), 2,0);//阻塞
msgtype>0 msgflg指定MSG_EXCEPT
msgrcv(msqid, &buf, sizeof(buf)-sizeof(long), 2,0|MSG_EXCEPT); //aaa
msgrcv(msqid, &buf, sizeof(buf)-sizeof(long), 2,0|MSG_EXCEPT); //ccc
msgrcv(msqid, &buf, sizeof(buf)-sizeof(long), 2,0|MSG_EXCEPT); //eeee
msgrcv(msqid, &buf, sizeof(buf)-sizeof(long), 2,0|MSG_EXCEPT); //ffff
msgrcv(msqid, &buf, sizeof(buf)-sizeof(long), 2,0|MSG_EXCEPT); //阻塞
msgtype<0
msgrcv(msqid, &buf, sizeof(buf)-sizeof(long), -4,0); //aaa
msgrcv(msqid, &buf, sizeof(buf)-sizeof(long), -4,0); //ccc
msgrcv(msqid, &buf, sizeof(buf)-sizeof(long), -4,0); //ddd
msgrcv(msqid, &buf, sizeof(buf)-sizeof(long), -4,0); //fff
msgrcv(msqid, &buf, sizeof(buf)-sizeof(long), -4,0); //eeee
msgrcv(msqid, &buf, sizeof(buf)-sizeof(long), -4,0); //阻塞

8)msgctl(删除、获取、修改队列信息)

格式:#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>int msgctl(int msqid, int cmd, struct msqid_ds *buf);
功能:消息队列控制(删除,获取信息,修改消息队列的信息)
参数:int msqid:消息的idint cmd:IPC_STAT:获取消息队列内核数据的IPC_SET:修改消息队列数据IPC_RMID:删除消息队列   ,第三个填 NULLstruct msqid_ds *buf,该指针存储获取以及修改对应内核的数据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 inqueue (nonstandard) */msgqnum_t       msg_qnum;     /* Current number of messagesin queue */msglen_t        msg_qbytes;   /* Maximum number of bytesallowed in queue */pid_t           msg_lspid;    /* PID of last msgsnd(2) */pid_t           msg_lrpid;    /* PID of last msgrcv(2) */};struct ipc_perm {key_t          __key;       /* Key supplied to msgget(2) */uid_t          uid;         /* Effective UID of owner */gid_t          gid;         /* Effective GID of owner */uid_t          cuid;        /* Effective UID of creator */gid_t          cgid;        /* Effective GID of creator */unsigned short mode;        /* Permissions */unsigned short __seq;       /* Sequence number */};
返回值:
如果指定IPC_STAT IPC_SET IPC_RMID 成功返回0,失败返回-1,跟新errno例如:删除消息队列
msgctl(msgid,IPC_RMID,NULL)
例如:获取消息队列的权限
struct msqid_ds buf;
msgctl(msgid,IPC_STAT,&buf);
printf("权限:%ld\n",buf.msg_perm.mode);
例如:修改消息队列的权限0777
1.先获取原来的属性
struct msqid_ds buf;
msgctl(msgid,IPC_STAT,&buf);
2.只修改权限
buf.msg_perm.mode=0777;
msgctl(msgid,IPC_SET,&buf);
printf("权限:%ld\n",buf.msg_perm.mode);

练习: 从信息队列中读取字符

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

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

相关文章

Webpack 5 核心机制详解与打包性能优化实践

&#x1f916; 作者简介&#xff1a;水煮白菜王&#xff0c;一个web开发工程师 &#x1f47b; &#x1f440; 文章专栏&#xff1a; 前端专栏 &#xff0c;记录一下平时在博客写作中&#xff0c;总结出的一些开发技巧和知识归纳总结✍。 感谢支持&#x1f495;&#x1f495;&am…

Manus AI与多语言手写识别

技术文章大纲&#xff1a;Manus AI与多语言手写识别 引言 手写识别技术的发展背景与市场需求Manus AI的定位与核心技术优势多语言场景下的挑战与机遇 Manus AI的核心技术架构 基于深度学习的端到端手写识别模型多模态数据融合&#xff08;笔迹压力、书写轨迹等&#xff09;…

Go与Python爬虫对比及模板实现

go语言和Python语言都可选作用来爬虫项目&#xff0c;因为python经过十几年的累积&#xff0c;各种库是应有尽有&#xff0c;学习也相对比较简单&#xff0c;相比GO起步较晚还是有很大优势的&#xff0c;么有对比就没有伤害&#xff0c;所以我利用一个下午&#xff0c;写个Go爬…

Vidwall: 支持将 4K 视频设置为动态桌面壁纸,兼容 MP4 和 MOV 格式

支持将 4K 视频设置为动态桌面壁纸&#xff0c;兼容 MP4 和 MOV 格式。只需将视频拖入应用界面&#xff0c;点击即可立即应用为桌面背景。 为桌面增添生动趣味的动态壁纸效果&#xff01;录制视频时设置动态背景&#xff0c;也能让画面更吸引人。 &#x1f4e5; https://apps.…

【LeetCode 热题 100】234. 回文链表——快慢指针+反转链表

Problem: 234. 回文链表 题目&#xff1a;给你一个单链表的头节点 head &#xff0c;请你判断该链表是否为回文链表。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 文章目录 整体思路完整代码时空复杂度时间复杂度&#xff1a;O(N)空间复杂度&#…

【源力觉醒 创作者计划】开源、易用、强中文:文心一言4.5或是 普通人/非AI程序员 的第一款中文AI?

前言 你有没有发现&#xff0c;AI 正在悄悄渗透进我们的生活&#xff1a;写文案、画插图、做PPT、答作业&#xff0c;它几乎无所不能&#x1f60d; &#xff01;但很多人可能会问&#xff1a; AI&#xff0c;我能用吗&#xff1f;用得起吗&#xff1f;适合我吗&#xff1f;特别…

【保姆级喂饭教程】Git图形化客户端Sourcetree安装及使用教程

目录 前言一、SourceTree简介二、安装教程三、使用教程1. 添加仓库 四、评价总结后记参考文献 前言 在查找Git Flow实现工具的时候&#xff0c;看到了SourceTree&#xff0c;支持Git Flow、GitHub Flow等多种Git工作流&#xff0c;安装简单学习一下。 一、SourceTree简介 Git的…

【kafka】kafka3.3.2常用命令

查看kafka服务版本 [rootlocalhost eicar]# kafka-server-start.sh --version [2025-06-23 11:10:54,106] INFO Registered kafka:typekafka.Log4jController MBean (kafka.utils.Log4jControllerRegistration$) 3.3.2 (Commit:b66af662e61082cb) [rootlocalhost eicar]#查看消…

LastActivityView -查看电脑上的所有操作记录

LastActivityView 是一款由 NirSoft 开发的免费工具&#xff0c;适用于 Windows 操作系统。它能够通过分析系统日志、Prefetch 文件、图标缓存数据库、注册表以及蓝屏 Dump 文件等多种来源&#xff0c;综合展示电脑从安装系统至今的所有操作记录。 LastActivityView 的功能 L…

English Practice - Day 3

Hi ChatGPT, I am back. can we start today’s english practice? Welcome back, Kelly! &#x1f60a; Yes — let’s begin today’s English practice! You’re doing great by showing up consistently. &#x1f4aa; Q&#xff1a; What’s the weather like today w…

quickbi看板内嵌入powerbi页面(含单点登录解决方法)

quickbi看板内嵌入powerbi页面&#xff08;含单点登录解决方法&#xff09; 实现步骤 要实现在quickbi看板中嵌入powerbi页面&#xff0c;分4步来实现。 1. 新建quickbi看板&#xff0c; 2. 添加内嵌页面 3. 获取Powerbi链接 4. 将powerbi链接粘贴到内嵌页面中 第一步&am…

CentOS-6如何配置网络设置IP? 笔记250706

CentOS-6如何配置网络设置IP? 笔记250706 1️⃣ 参考 1 CentOS 6 网络配置完全指南 在 CentOS 6 中配置网络设置主要涉及修改 /etc/sysconfig/network-scripts/ 目录下的配置文件。以下是详细配置步骤&#xff1a; 一、配置静态 IP 地址 1. 编辑网卡配置文件 vi /etc/sys…

WPF学习笔记(24)命令与ICommand接口

命令与ICommand接口一、命令1. ICommandSource2. 示例3. CommandBinding二、ICommand1.ICommand接口2. ICommand用法3. CanExecute总结一、命令 官方文档&#xff1a;https://learn.microsoft.com/zh-cn/dotnet/desktop/wpf/advanced/commanding-overview 1. ICommandSource 官…

TCP长连接保持在线状态

TCP长连接是指在一次TCP连接建立后&#xff0c;保持连接状态较长时间&#xff0c;用于多次数据传输&#xff0c;而不是每次通信后立即断开。这种机制对于需要频繁通信的应用非常重要。 保持TCP长连接在线的方法 1. 心跳机制(Heartbeat) 实现原理&#xff1a;定期发送小数据包…

华为OD机试 2025B卷 - 报文响应时间 (C++ Python JAVA JS C语言)

2025B卷目录点击查看: 华为OD机试2025B卷真题题库目录|机考题库 + 算法考点详解 2025B卷 100分题型 题目描述 IGMP 协议中,有一个字段称作最大响应时间 (Max Response Time) ,HOST收到查询报文,解折出 MaxResponsetime 字段后,需要在 (0,MaxResponseTime] 时间 (s) 内选…

深入理解微服务中的服务注册与发现(Consul)

在当今数字化浪潮下&#xff0c;微服务架构凭借其高内聚、低耦合的特性&#xff0c;成为众多企业构建复杂应用系统的首选方案。然而&#xff0c;随着服务数量的不断增加&#xff0c;服务之间的调用与管理变得愈发复杂。这时&#xff0c;服务注册与发现就如同微服务架构中的 “导…

Zephyr【2】-----内核调度[1]

内核调度 Zephyr 内核的调度器是基于什么原则选择当前执行线程的&#xff1f; 总是选择优先级最高的就绪线程作为当前线程。 当多个线程优先级相同时&#xff0c;调度器会如何选择&#xff1f; 线程的 “就绪状态” 和 “非就绪状态” 分别指什么&#xff1f;哪些情况会导致…

LangChain内置工具包和联网搜索

目录 一、什么是智能体?工具包又是什么&#xff1f; 二、智能体(Agent)的出现是为了解决哪些问题&#xff1f; 三、LangChain里面创建工具方式 3.1 tool 装饰器&#xff1a;用来定义一个简单的工具函数,, 可以直接给函数加上这个装饰器&#xff0c;让函数成为可调用的工具…

用c++做游戏开发至少要掌握哪些知识?

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于用C做游戏开发的相关内容&#xff01; 关…

vue3使用summernote

一、安装 npm install summernote-vue jquery summernote bootstrap popperjs/core二、summernoteEditor.vue <template><div ref"editorRef"></div> </template><script setup> import {ref, onMounted, onBeforeUnmount, watch} f…