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

探索进程控制第一弹(进程终止、进程等待)

文章目录

  • 进程创建
    • 初识fork函数
    • fork函数返回值
    • fork常规用法
    • fork调用失败的原因
  • 写时拷贝
  • 进程终止
    • 进程终止是在做什么?
    • 进程终止的情况
      • 代码跑完,结果正确/不正确
      • 代码异常终止
    • 如何终止
  • 进程等待
    • 概述
    • 进程等待方法
      • wait方法
      • waitpid

在这里插入图片描述

进程创建

初识fork函数

在linux中fork函数时非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。

#include <unistd.h>
pid_t fork(void);

返回值:自进程中返回0,父进程返回子进程id,出错返回-1。

进程=内核相关管理数据结构(task_struct、mm_struct、页表)+代码和数据

对于每一个进程都需要:

  • 分配新的内存块和内核数据结构给子进程
  • 将父进程部分数据结构内容拷贝至子进程
  • 添加子进程到系统进程列表当中
  • fork返回,开始调度器调度

在这里插入图片描述

如何理解进程具有独立性??子进程中也有相关管理数据结构也有自己的代码和数据,代码和数据虽然和父进程共享,但是和父进程相互不影响,数据的部分是以写时拷贝时私有,不写时拷贝相当于共享。

当一个进程调用fork之后,就有两个二进制代码相同的进程。而且它们都运行到相同的地方。但每个进程都将可以开始它们自己的旅程。

fork函数返回值

  • 子进程返回0
  • 父进程返回的是子进程的pid

如何做到有两个返回值?
探索父进程和子进程 文章中有详细解释。

为什么给父进程返回的是子进程的pid,给子进程返回0?
父进程必须知道子进程的pid,方便后续对子进程进行标识,进而进行管理;子进程需要通过返回0,来看是否创建成功。

fork常规用法

  • 一个父进程希望复制自己,使父子进程同时执行不同的代码段。例如,父进程等待客户端请求,生成子进程来处理请求。
  • 一个进程要执行一个不同的程序。例如子进程从fork返回后,调用exec函数

fork调用失败的原因

  • 系统中有太多的进程
  • 实际用户的进程数超过了限制

写时拷贝

通常,父子代码共享,父子再不写入时,数据也是共享的,当任意一方试图写入,便以写时拷贝的方式各自一份副本。

在这里插入图片描述


进程终止

进程终止是在做什么?

在进程创建的时候,是先有内核数据结构,再有的代码和数据。
终止一个进程的本质是在释放曾经的代码和数据所占据的空间,释放内核数据结构。
在释放内核数据结构时,PCB会延迟释放。

进程终止的情况

代码跑完,结果正确/不正确

在这里插入图片描述

main函数的返回值是100,通过echo $?查询。在系统中有一个变量叫做?,查看这个变量使用$?,访问变量内容都可以使用echoecho是内建命令,打印的都是bash内部的变量数据。
$?表示父进程bash获取到的最近一个子进程退出的退出码。退出码为0表示成功,非0表示失败,不同的非0值一方面表示失败,另一方面表示失败原因,每个数字的错误描述都是由操作系统规定,对应的错误描述都是一个字符串。因此平时在写代码时,main函数内部都是return 0,我们在编写C/C++代码都是默认成功的。

#include<stdio.h>    
#include<unistd.h>    
#include<string.h>    int main()    
{    for(int errcode=0;errcode<=255;errcode++)    {    printf("%d:%s\n",errcode,strerror(errcode));                                                                                         }    printf("I am process,pid:%d,ppid:%d\n",getpid(),getppid());    sleep(2);    return 100;    
}    

运行结果:

[gwj@iZf8zhv7mi2thjdxsptkb8Z lesson16]$ make
gcc -o myprocess myprocess.c -std=c99
[gwj@iZf8zhv7mi2thjdxsptkb8Z lesson16]$ ./myprocess 
0:Success
1:Operation not permitted
2:No such file or directory
3:No such process
4:Interrupted system call
5:Input/output error
6:No such device or address
7:Argument list too long
8:Exec format error
9:Bad file descriptor
10:No child processes
11:Resource temporarily unavailable
12:Cannot allocate memory
13:Permission denied
14:Bad address
15:Block device required
16:Device or resource busy
17:File exists
18:Invalid cross-device link
19:No such device
20:Not a directory
21:Is a directory
22:Invalid argument
23:Too many open files in system
24:Too many open files
25:Inappropriate ioctl for device
26:Text file busy
27:File too large
28:No space left on device
29:Illegal seek
30:Read-only file system
31:Too many links
32:Broken pipe
33:Numerical argument out of domain
34:Numerical result out of range
35:Resource deadlock avoided
36:File name too long
37:No locks available
38:Function not implemented
39:Directory not empty
40:Too many levels of symbolic links
41:Unknown error 41
42:No message of desired type
43:Identifier removed
44:Channel number out of range
45:Level 2 not synchronized
46:Level 3 halted
47:Level 3 reset
48:Link number out of range
49:Protocol driver not attached
50:No CSI structure available
51:Level 2 halted
52:Invalid exchange
53:Invalid request descriptor
54:Exchange full
55:No anode
56:Invalid request code
57:Invalid slot
58:Unknown error 58
59:Bad font file format
60:Device not a stream
61:No data available
62:Timer expired
63:Out of streams resources
64:Machine is not on the network
65:Package not installed
66:Object is remote
67:Link has been severed
68:Advertise error
69:Srmount error
70:Communication error on send
71:Protocol error
72:Multihop attempted
73:RFS specific error
74:Bad message
75:Value too large for defined data type
76:Name not unique on network
77:File descriptor in bad state
78:Remote address changed
79:Can not access a needed shared library
80:Accessing a corrupted shared library
81:.lib section in a.out corrupted
82:Attempting to link in too many shared libraries
83:Cannot exec a shared library directly
84:Invalid or incomplete multibyte or wide character
85:Interrupted system call should be restarted
86:Streams pipe error
87:Too many users
88:Socket operation on non-socket
89:Destination address required
90:Message too long
91:Protocol wrong type for socket
92:Protocol not available
93:Protocol not supported
94:Socket type not supported
95:Operation not supported
96:Protocol family not supported
97:Address family not supported by protocol
98:Address already in use
99:Cannot assign requested address
100:Network is down
101:Network is unreachable
102:Network dropped connection on reset
103:Software caused connection abort
104:Connection reset by peer
105:No buffer space available
106:Transport endpoint is already connected
107:Transport endpoint is not connected
108:Cannot send after transport endpoint shutdown
109:Too many references: cannot splice
110:Connection timed out
111:Connection refused
112:Host is down
113:No route to host
114:Operation already in progress
115:Operation now in progress
116:Stale file handle
117:Structure needs cleaning
118:Not a XENIX named type file
119:No XENIX semaphores available
120:Is a named type file
121:Remote I/O error
122:Disk quota exceeded
123:No medium found
124:Wrong medium type
125:Operation canceled
126:Required key not available
127:Key has expired
128:Key has been revoked
129:Key was rejected by service
130:Owner died
131:State not recoverable
132:Operation not possible due to RF-kill
133:Memory page has hardware error
134:Unknown error 134
135:Unknown error 135
136:Unknown error 136
137:Unknown error 137
138:Unknown error 138
139:Unknown error 139
140:Unknown error 140
141:Unknown error 141
142:Unknown error 142
143:Unknown error 143
144:Unknown error 144
145:Unknown error 145
146:Unknown error 146
147:Unknown error 147
148:Unknown error 148
149:Unknown error 149
150:Unknown error 150
151:Unknown error 151
152:Unknown error 152
153:Unknown error 153
154:Unknown error 154
155:Unknown error 155
156:Unknown error 156
157:Unknown error 157
158:Unknown error 158
159:Unknown error 159
160:Unknown error 160
161:Unknown error 161
162:Unknown error 162
163:Unknown error 163
164:Unknown error 164
165:Unknown error 165
166:Unknown error 166
167:Unknown error 167
168:Unknown error 168
169:Unknown error 169
170:Unknown error 170
171:Unknown error 171
172:Unknown error 172
173:Unknown error 173
174:Unknown error 174
175:Unknown error 175
176:Unknown error 176
177:Unknown error 177
178:Unknown error 178
179:Unknown error 179
180:Unknown error 180
181:Unknown error 181
182:Unknown error 182
183:Unknown error 183
184:Unknown error 184
185:Unknown error 185
186:Unknown error 186
187:Unknown error 187
188:Unknown error 188
189:Unknown error 189
190:Unknown error 190
191:Unknown error 191
192:Unknown error 192
193:Unknown error 193
194:Unknown error 194
195:Unknown error 195
196:Unknown error 196
197:Unknown error 197
198:Unknown error 198
199:Unknown error 199
200:Unknown error 200
201:Unknown error 201
202:Unknown error 202
203:Unknown error 203
204:Unknown error 204
205:Unknown error 205
206:Unknown error 206
207:Unknown error 207
208:Unknown error 208
209:Unknown error 209
210:Unknown error 210
211:Unknown error 211
212:Unknown error 212
213:Unknown error 213
214:Unknown error 214
215:Unknown error 215
216:Unknown error 216
217:Unknown error 217
218:Unknown error 218
219:Unknown error 219
220:Unknown error 220
221:Unknown error 221
222:Unknown error 222
223:Unknown error 223
224:Unknown error 224
225:Unknown error 225
226:Unknown error 226
227:Unknown error 227
228:Unknown error 228
229:Unknown error 229
230:Unknown error 230
231:Unknown error 231
232:Unknown error 232
233:Unknown error 233
234:Unknown error 234
235:Unknown error 235
236:Unknown error 236
237:Unknown error 237
238:Unknown error 238
239:Unknown error 239
240:Unknown error 240
241:Unknown error 241
242:Unknown error 242
243:Unknown error 243
244:Unknown error 244
245:Unknown error 245
246:Unknown error 246
247:Unknown error 247
248:Unknown error 248
249:Unknown error 249
250:Unknown error 250
251:Unknown error 251
252:Unknown error 252
253:Unknown error 253
254:Unknown error 254
255:Unknown error 255
I am process,pid:32312,ppid:31371

对应的错误码都表示一种错误。

父进程为什么知道子进程退出码?父进程要知道子进程的退出情况(失败了还是成功了,失败的原因是什么),bash会反馈给用户。

举个例子:

在这里插入图片描述

进程的退出码存在的意义是告诉关心方(父进程),我把任务执行的怎么样了。既然把子进程创建出来,就要让父进程得到信息。

在这里插入图片描述

不是说echo $?保存的是最近一个子进程退出的退出码吗?那上图怎么解释?方框中第一个echo $?执行的命令是查看process的退出码,第二个echo $?查看的是第一个echo $?的退出码,虽然echo是一个内建命令,但是也是当做进程来看待。

进程的退出码可以使用系统官方的定义,你也可以自定义一个退出码。

代码异常终止

代码执行时,出现了异常,提前退出,一旦进程出现异常,退出码有没有意义了

vs编写程序运行时,程序崩溃了,本质是操作系统发现你的程序做了不该做的事情,操作系统杀掉了你的进程。

为什么进程会出现异常?
本质上是因为进程收到了操作系统发出的信号。

段错误,操作系统提前终止进程。

在这里插入图片描述
尽管书写的代码进程没有错误,但是接收到了信号,就会有段错误。

进程退出时,我们可以看进程退出信号是多少来判断进程为什么异常。

进程退出的三种情况:
代码运行完毕,结果正确
代码运行完毕,结果不正确
代码异常终止

因此,衡量一个进程退出,我们只需要看两个数字:退出码、退出信号

如何终止

  1. main函数中直接return,表示进程终止(非main函数,return函数结束)
  2. 代码调用exit(),注意:在代码任意位置调用都表示进程终止。
#include<stdio.h>    
#include<unistd.h>    
#include<string.h>    
#include<stdlib.h>                                                 
int main()    
{    while(1)    {    printf("I am process,pid:%d,ppid:%d\n",getpid(),getppid());sleep(2);    exit(123);    }    return 100;    
}  

在这里插入图片描述

#include <unistd.h>
void exit(int status);

exit最后也会调用exit, 但在调用exit之前,还做了其他工作:

  • 执行用户通过 atexit或on_exit定义的清理函数。
  • 关闭所有打开的流,所有的缓存数据均被写入
  • 调用_exit
  1. 调用_exit()函数
#include <unistd.h>
void _exit(int status);

参数:status 定义了进程的终止状态,父进程通过wait来获取该值
说明:虽然status是int,但是仅有低8位可以被父进程所用。所以_exit(-1)时,在终端执行$?发现返回值是255。

#include<stdio.h>    
#include<unistd.h>    
#include<string.h>    
#include<stdlib.h>                                                 
int main()    
{    while(1)    {    printf("I am process,pid:%d,ppid:%d\n",getpid(),getppid());sleep(2);    _exit(-1);    }    return 100;    
}  

在这里插入图片描述


exit_exit区别:
exit会在程序退出时,冲刷缓冲区,_exit不会。

在这里插入图片描述

进程等待

概述

什么是进程等待?
任何子进程,在退出的情况下,一般必须要被父进程等待。 进程在退出的时候,如果父进程不管不顾,退出进程,处于僵尸状态(Z),存在内存泄漏。


为什么?

  1. 父进程通过等待,解决子进程退出的僵尸问题,回收系统资源(一定要考虑的)
  2. 父进程获取子进程的退出信息,知道子进程退出原因(可选的功能)

进程等待方法

wait方法

#include<sys/types.h>
#include<sys/wait.h>
pid_t wait(int*status);

返回值:
成功返回被等待进程pid,失败返回-1。
参数:
输出型参数,获取子进程退出状态,不关心则可以设置成为NULL。

代码势力:

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>void ChildRun()
{int cnt=5;while(cnt){printf("I am child process,pid:%d,ppid:%d,cnt=%d\n",getpid(),getppid(),cnt);sleep(1);cnt--;}
}int main()
{printf("I am father,pid:%d,ppid:%d\n",getpid(),getppid());pid_t id=fork();if(id==0)                                                                        {//childChildRun();printf("child process quit...\n");exit(0);}sleep(10);//fatherpid_t rid=wait(NULL);if(rid>0){printf("wait process,rid:%d\n",rid);}sleep(3);printf("father process quit...\n");return 0;
}

运行结果:

在这里插入图片描述

在上述代码中,先进入父进程,然后子进程运行五次后子进程退出,然后休眠10秒,处于僵尸状态,紧接着进程等待,然后父进程退出,程序运行结束。由此可以看出,等待会解决进程的僵尸问题。

将上述代码sleep(10)代码注释掉,子进程运行5秒后直接退出,立马执行父进程等待。如果子进程没有退,其实父进程一直在阻塞等待。子进程本身是软件,父进程本质是在等待某种软件就绪。
进程的等待本质是将进程的PCB列入等待队列。那么如何理解父进程阻塞等待子进程?父进程不被调度,在执行wait发现子进程还没有退出,父进程就不要调度,实际上就是将父进程PCB列入等待队列,处于S状态(非运行状态),等到子进程退出,唤醒父进程。

waitpid

#include <sys/types.h>
#include <sys/wait.h>pid_t wait(int *status);pid_t waitpid(pid_t pid, int *status, int options);int  waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
  • 返回值:

当正常返回的时候waitpid返回收集到的子进程的进程ID;
如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0;
如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在;

  • 参数:

  • [ ]

  • pid:

  1. Pid=-1,等待任一个子进程。与wait等效。
    pid_t rid=waitpid(-1,NULL,0);等待任何一个子进程退出,哪一个进程退了,就对应返回哪一个进程的pid。等同于 pid_t rid=wait(NULL);

  2. Pid>0.等待其进程ID与pid相等的子进程。

  3. pid_t rid=waitpid(id,NULL,0);

  • status:典型输出型参数
  1. WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出)
  2. WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。(查看进程的退出码)

以位图的形式返回
在这里插入图片描述
退出码范围:0~255
信号终止:128个

代码:

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>void ChildRun()
{int cnt=5;while(cnt){printf("I am child process,pid:%d,ppid:%d,cnt=%d\n",getpid(),getppid(),cnt);sleep(1);cnt--;}
}int main()
{printf("I am father,pid:%d,ppid:%d\n",getpid(),getppid());pid_t id=fork();if(id==0)                                                                                                                        {//childChildRun();printf("child process quit...\n");exit(1);}sleep(7);//father//pid_t rid=wait(NULL);int status=0;pid_t rid=waitpid(id,&status,0);if(rid>0){printf("wait process,rid:%d\n",rid);}sleep(3);printf("father process quit,status:%d,child quit code:%d,child quit signal:%d\n",status,(status>>8)&0xFF,status & 0x7F);return 0;
}

运行结果:

在这里插入图片描述

宏定义方式等待:

在这里插入图片描述

等待是必须的,但获取子进程的退出信息不是必须的。

如果子进程没有退出,而父进程在执行waitpid进行等待,阻塞等待,这本质上是进程阻塞,waitpid在等待某种条件发生(子进程退出),在等待期间,父进程什么也没干。

接下来就介绍非阻塞等待!!!

  • options:
    WNOHANG: 若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。若正常结束,则返回该子进程的ID。
    pid_t>0:等待成功,子进程退出,并且父进程回收成功
    pid_t<0:等待失败
    pid_t==0:检测成功,但是子进程还没有退出,需要进行下一次重复等待。
    非阻塞等待的时候+循环=非阻塞轮询
    好处:允许父进程做一些其他的事情
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>void ChildRun()
{int cnt=5;while(cnt){printf("I am child process,pid:%d,ppid:%d,cnt=%d\n",getpid(),getppid(),cnt);sleep(1);cnt--;}
}int main()
{printf("I am father,pid:%d,ppid:%d\n",getpid(),getppid());pid_t id=fork();
if(id==0){//childChildRun();printf("child process quit...\n");exit(1);}//fatherwhile(1)                                                                                                                               {int status=0;pid_t rid=waitpid(id,&status,WNOHANG);if(rid==0){sleep(1);printf("child is running,father check next time!\n");}else if(id>0){if(WIFEXITED(status)){printf("child quit success,child exit code:%d\n",WEXITSTATUS(status));}else {printf("child quit unnormal!\n");}break;}else {printf("waitpid failed!\n");break;}}
}

在这里插入图片描述


在这里插入图片描述

相关文章:

探索进程控制第一弹(进程终止、进程等待)

文章目录 进程创建初识fork函数fork函数返回值fork常规用法fork调用失败的原因 写时拷贝进程终止进程终止是在做什么&#xff1f;进程终止的情况代码跑完&#xff0c;结果正确/不正确代码异常终止 如何终止 进程等待概述进程等待方法wait方法waitpid 进程创建 初识fork函数 在…...

在mac环境下使用shell脚本实现tree命令

文章目录 使用ls实现tree使用find实现tree 使用ls实现tree 实现思路 使用ls -F 打印文件类型&#xff0c;如果是目录后面跟/&#xff0c;如果是可执行文件后面跟*&#xff1b;使用grep -v /$ 筛选文件排除目录&#xff0c;-v为反向筛选&#xff1b;使用grep /$ 仅筛选目录&am…...

递归时间复杂度分析方法:Master 定理

编写算法时&#xff0c;可能因为对自己代码的复杂度的不清晰而导致错失良机&#xff0c;对于普通的递推或者说循环的代码&#xff0c;仅用简单的调和级数或者等差数列和等比数列即可分析&#xff0c;但是对于递归的代码&#xff0c;简单的递归树法并不方便&#xff0c;理解并记…...

实例名不规范导致mds创建失败

概述 在部署ceph集群时&#xff0c;规划主机名、关闭防火墙、配置免密、关闭selinux&#xff0c;配置hosts文件这几步同样重要&#xff0c;都是初期部署一次麻烦&#xff0c;方便后续运维的动作。遇到过很多前期稀里糊涂部署&#xff0c;后续运维和配置时候各种坑。 近期遇到…...

OpenGL中的纹理过滤GL_NEAREST和GL_LINEAR

一、GL_NEAREST&#xff08;最近邻插值&#xff09; 1.1 原理 当需要从纹理中采样颜色时&#xff0c;GL_NEAREST模式会选择离采样点最近的纹理像素&#xff08;通常是最接近采样点的纹理元素的中心&#xff09;&#xff0c;并直接使用该像素的颜色值作为输出。这种模式不进行任…...

vue 性能优化

data 层级不要太深 data 层级太深会增加响应式监听的计算&#xff0c;导致页面初次渲染时卡顿。 合理使用 v-show 和 v-if 频繁切换时&#xff0c;使用 v-show无需频繁切换时&#xff0c;使用 v-if 合理使用 computed computed 有缓存&#xff0c;data 不变时不会重新计算&…...

互联网大厂ssp面经(操作系统:part1)

1. 什么是进程和线程&#xff1f;它们之间有什么区别&#xff1f; a. 进程是操作系统中运行的一个程序实例。它拥有独立的地址空间和资源&#xff0c;可以独立执行。 b. 线程是进程内的一个执行单元&#xff0c;一个进程可以包含多个线程。 c. 线程共享进程的资源&#xff0c;…...

Android Activity 启动涉及几个进程

Zygote进程: Zygote进程在Android系统启动时被初始创建&#xff0c;并且初始化了虚拟机&#xff08;Dalvik或ART&#xff09;&#xff0c;预加载了Android系统的核心类库。所有的Android应用进程都是通过fork()从Zygote进程派生出来的&#xff0c;这允许应用快速启动&#xff0…...

说说你对链表的理解?常见的操作有哪些?

一、是什么 链表&#xff08;Linked List&#xff09;是一种物理存储单元上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的&#xff0c;由一系列结点&#xff08;链表中每一个元素称为结点&#xff09;组成 每个结点包括两个部分&…...

每天五分钟深度学习:逻辑回归算法的损失函数和代价函数是什么?

本文重点 前面已经学习了逻辑回归的假设函数,训练出模型的关键就是学习出参数w和b,要想学习出这两个参数,此时需要最小化逻辑回归的代价函数才可以训练出w和b。那么本节课我们将学习逻辑回归算法的代价函数是什么? 为什么不能平方差损失函数 线性回归的代价函数我们使用…...

llama-factory SFT系列教程 (二),大模型在自定义数据集 lora 训练与部署

文章目录 简介支持的模型列表2. 添加自定义数据集3. lora 微调4. 大模型 lora 权重&#xff0c;部署问题 参考资料 简介 文章列表&#xff1a; llama-factory SFT系列教程 (一)&#xff0c;大模型 API 部署与使用llama-factory SFT系列教程 (二)&#xff0c;大模型在自定义数…...

C语言游戏实战(11):贪吃蛇大作战(多人对战)

成果展示&#xff1a; 贪吃蛇&#xff08;多人对战&#xff09; 前言&#xff1a; 这款贪吃蛇大作战是一款多人游戏&#xff0c;玩家需要控制一条蛇在地图上移动&#xff0c;吞噬其他蛇或者食物来增大自己的蛇身长度和宽度。本游戏使用C语言和easyx图形库编写&#xff0c;旨在…...

腾讯测试岗位的面试经历与经验分享【一面、二面与三面】

腾讯两个月的实习一转眼就结束了,回想起当时面试的经过,感觉自己是跌跌撞撞就这么过了,多少有点侥幸.马上腾讯又要来校招了,对于有意愿想投腾讯测试岗位的同学们,写了一些那时候面试的经历和自己的想法,算不上经验&#xff0c;仅供参考吧! 一面 — —技术基础&#xff0c;全面…...

手机移动端网卡信息获取原理分析

有些场景我们需要获取当前手机上的网卡信息&#xff08;如双卡双待、Wifi等&#xff09;。本文准备研究一下这块的原理&#xff0c;以便更好的掌握相关技术原理。 1、底层系统接口 getifaddrs 使用 getifaddrs 接口可以达到我们的目的&#xff0c;该接口会返回本地所有网卡的信…...

无人新零售引领的创新浪潮

无人新零售引领的创新浪潮 在数字化时代加速演进的背景下&#xff0c;无人新零售作为商业领域的一股新兴力量&#xff0c;正以其独特的高效性和便捷性重塑着传统的购物模式&#xff0c;开辟了一条充满创新潜力的发展道路。 依托人脸识别、物联网等尖端技术&#xff0c;无人新…...

SD-WAN提升企业网络体验

在现代企业中&#xff0c;网络体验已成为提升工作效率与业务质量的关键因素。SD-WAN技术的出现&#xff0c;以其独特的优势&#xff0c;为企业提供了优化网络连接、加速数据传输、提升服务质量和应用访问体验&#xff0c;以及增强网络稳定性的解决方案。接下来&#xff0c;我们…...

Docker搭建Let‘s Encrypt

Let’s Encrypt是一个免费、开放和自动化的证书颁发机构&#xff08;CA&#xff09;&#xff0c;它提供了一种简单、无需重复的机制来获取和更新SSL/TLS证书。Let’s Encrypt Docker镜像允许用户在容器化环境中轻松部署和使用Let’s Encrypt的服务。 主要功能包括&#xff1a;…...

单链表讲解

一.链表的概念以及结构 链表是一种物理结构上不连续&#xff0c;逻辑结构上连续的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的。 链表的结构与火车是类似的&#xff0c;一节一节的&#xff0c;数据就像乘客一样在车厢中一样。 与顺序表不同的…...

DFS算法系列 回溯

DFS算法系列-回溯 文章目录 DFS算法系列-回溯1. 算法介绍2. 算法应用2.1 全排列2.2 组合2.3 子集 3. 总结 1. 算法介绍 回溯算法是一种经典的递归算法&#xff0c;通常被用来解决排列问题、组合问题和搜索问题 基本思想 从一个初始状态开始&#xff0c;按一定的规则向前搜索&…...

Linux C应用编程:MQTT物联网

1 MQTT通信协议 MQTT&#xff08;Message Queuing Telemetry Transport&#xff0c;消息队列遥测传 输&#xff09;是一种基于客户端-服务端架构的消息传输协议&#xff0c;如今&#xff0c;MQTT 成为了最受欢迎的物联网协议&#xff0c;已广泛应用于车联网、智能家居、即时聊…...

企业常用Linux文件命令相关知识+小案例

远程连接工具无法连接VMWARE&#xff1a; 如果发现连接工具有时连不上&#xff0c;ip存在&#xff0c;这时候我们查看网络编辑器&#xff0c;更多配置&#xff0c;看vnet8是不是10段&#xff0c;nat设置是否是正确的&#xff1f; 软件重启一下虚机还原一下网络编辑器 查看文件…...

Istio介绍

1.什么是Istio Istio是一个开源的服务网格&#xff08;Service Mesh&#xff09;框架&#xff0c;它提供了一种简单的方式来为部署在Kubernetes等容器编排平台上的微服务应用添加网络功能。Istio的核心功能包括&#xff1a; 服务治理&#xff1a;Istio能够帮助管理服务之间的…...

代码随想录算法训练营第四十七天|leetcode115、392题

一、leetcode第392题 本题要求判断s是否为t的子序列&#xff0c;因此设置dp数组&#xff0c;dp[i][j]的含义是下标为i-1的子串与下标为j-1的子串相同字符的个数&#xff0c;可得递推公式是通过s[i-1]和t[j-1]是否相等区分。 具体代码如下&#xff1a; class Solution { publ…...

将Ubuntu18.04默认的python3.6升级到python3.8

1、查看现有的 python3 版本 python3 --version 2、安装 python3.8 sudo apt install python3.8 3、将 python3.6 和 3.8 添加到 update-alternatives sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 1 sudo update-alternatives --insta…...

Python和Java哪个更适合后端开发?

Python和Java都是强大的后端开发语言&#xff0c;它们各自有鲜明的特点和适用场景。选择哪一个更适合后端开发&#xff0c;主要取决于具体的项目需求、团队技术栈、个人技能偏好以及长期发展考虑等因素。 下面是两者在后端开发中的优势和劣势&#xff1a; 「Python&#xff1…...

Python+pytest接口自动化之cookie绕过登录(保持登录状态)

前言 我们今天来聊聊pythonpytest接口自动化之cookie绕过登录&#xff08;保持登录状态&#xff09;&#xff0c;在编写接口自动化测试用例或其他脚本的过程中&#xff0c;经常会遇到需要绕过用户名/密码或验证码登录&#xff0c;去请求接口的情况&#xff0c;一是因为有时验证…...

什么数据集成(Data Integration):如何将业务数据集成到云平台?

说到数据集成&#xff08;Data Integration&#xff09;&#xff0c;简单地将所有数据倒入数据湖并不是解决办法。 在这篇文章中&#xff0c;我们将介绍如何轻松集成数据、链接不同来源的数据、将其置于合适的环境中&#xff0c;使其具有相关性并易于使用。 数据集成&#xff1…...

国外EDM邮件群发多少钱?哪个软件好?

在当今全球化市场环境下&#xff0c;电子邮件营销作为最有效的数字营销渠道之一&#xff0c;其影响力不容忽视。而高效精准的EDM&#xff08;Electronic Direct Mail&#xff09;邮件营销策略更是企业拓展海外市场、提升品牌知名度的关键手段。云衔科技以其创新的智能EDM邮件营…...

C语言入门算法——回文数

题目描述&#xff1a; 若一个数&#xff08;首位不为零&#xff09;从左向右读与从右向左读都一样&#xff0c;我们就将其称之为回文数。 例如&#xff1a;给定一个十进制数 56&#xff0c;将 56 加 65&#xff08;即把 56 从右向左读&#xff09;&#xff0c;得到 121 是一个…...

OceanBase—操作实践

文档结构 1、概念简介2、核心设计3、操作实践3.3、数据同步 官方文档&#xff1a;https://www.oceanbase.com/docs/oceanbase-database-cn 1、概念简介 版本分为社区版和企业版&#xff0c;其中企业版兼容MySQL 和Oracle数据库语法&#xff1b; 2、核心设计 存储层 复制层 …...

网站定制开发是什么意思/网络推广有几种方法

配置了 log4j 在xml 中&#xff0c;但控制台输出为空的解决办法 1、 在Mybatis 的核心配置文件内添加&#xff1a; <setting name"logImpl" value"LOG4J"/> </settings>2、在当前工程的pom 文件内添加 <dependencies><dependency>…...

人大网站建设不足/今日新闻国际最新消息

uci set network.lan.ipaddr[lan ip] 使用pppoe设置 Shell代码 uci set network.wan.protopppoe //设置wan口类型为pppoe uci set network.wan.username[上网帐户] uci set network.wan.password[上网密码] //这两行设置pppoe用户名和密码 如果要挂在上级路由下面,就…...

电子商务网站建设与规划视频/360站长工具

关联博客&#xff1a;kubernetes/k8s CSI分析-容器存储接口分析 kubernetes/k8s CRI分析-容器运行时接口分析 概述 kubernetes的设计初衷是支持可插拔架构&#xff0c;从而利于扩展kubernetes的功能。在此架构思想下&#xff0c;kubernetes提供了3个特定功能的接口&#xff0…...

头条网站模版/信息流优化师培训

ubuntu安裝了wireshark&#xff0c;發現打不開網絡接口&#xff0c;后來從網上得知要用sudo從命令行執行&#xff0c;確實可以&#xff0c;但是執行過程中一直要開一個命令行窗口&#xff0c;不爽&#xff0c;想直接用單擊圖標的方法運行之&#xff0c;在網上查詢找到以下兩個方…...

日照又做渔家网站的吗/app软件推广平台

三年前&#xff0c;我刚刚从大学毕业&#xff0c;来到了一家外包公司工作。这份工作对于我来说是个好的起点&#xff0c;因为它让我接触到了真正的企业项目和实际的开发流程。但是&#xff0c;随着时间的流逝&#xff0c;我发现这份工作并没有给我带来足够的成长和挑战。 三年…...

2017年网站开发用什么语言/推广电话

原标题&#xff1a;有哪些大学的外号特别搞笑&#xff1f;网友&#xff1a;有些名称真是神了&#xff01;网友一&#xff1a;华南师范大学&#xff0c;又称华南吃饭大学&#xff0c;简称滑湿&#xff0c;别称华南师太&#xff0c;雨季又名华南水上乐园&#xff0c;文青叫华师威…...