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

Linux之线程管理

目录

第1关:创建线程

任务描述

相关知识

使用pthread_create函数创建线程

编程要求

答案:

第2关:线程挂起

任务描述

相关知识

使用pthread_join挂起线程

编程要求

答案:

第3关:线程终止

任务描述

相关知识

使用pthread_exit退出线程

使用pthread_cancel退出线程

编程要求

答案: 


第1关:创建线程

任务描述

通常我们编写的程序都是单进程,如果在一个进程中没有创建新的线程,则这个单进程程序也就是单线程程序。本关我们将介绍如何在一个进程中创建多个线程。

本关任务:学会使用C语言在Linux系统中使用pthread_create库函数创建一个新的线程。

相关知识

通常我们编写的程序都是单线程程序,单线程的程序都是按照一定的顺序按序的执行。有些情况下,我们需要在一个进程中同时执行多个控制流程,这时候线程就派上了用场。例如,我们需要实现一个在线音乐播放器,一方面我们在线播放用户选中的音乐,另一方面又需要同时下载曲子,这些任务需要同时被执行,而不是按序一个一个的执行,这样才会使得用户一边播放音乐,一边下载自己喜欢的曲子。针对以上需求,我们可以用多线程实现,一个线程专门在线播放用户选中的音乐,另外一个线程专门用户下载曲子。

通常,一个进程只包含一个线程,我们把这个线程叫做主线程,例如main函数就是一个主线程。如果在主线程里创建多个线程,那么程序就会在创建线程的地方产生分支,变成了多个程序来同时运行。这似乎和我们以前学习的多进程一样,其实背后的原理还是有所区别。

在多进程中,子进程是通过拷贝父进程的地址空间来实现,而在多线程中,同一进程中的所有线程都是共享程序代码,一段代码可以被多个线程来执行。

Linux系统中,我们可以通过pthread_create函数来创建线程。我们可以使用man命令来查询该函数的使用方法。具体的查询命令为:man 3 pthread_create

使用pthread_create函数创建线程

pthread_create函数的具体的说明如下:

需要的头文件如下:

#include <pthread.h>

函数格式如下:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
thread:该参数是一个指针,当线程创建成功后,用来返回创建的线程ID;
attr:该参数用于指定线程的属性,NULL表示使用默认属性,通常我们使用默认属性;
start_routine:该参数为一个函数指针,指向线程创建后要调用的函数,也被称为线程函数;
arg:该参数指向传递给线程函数的参数;

函数返回值说明: 调用成功,pthread_create返回值为0;调用失败返回一个非零的值。

注意:

pthread_create一旦调用成功,新创建的线程将开始运行第3个参数所指向的函数,原来的线程继续往下运行。由于线程是第三库所提供的,因此在编译包含线程的程序时,我们需要手动链接线程库,只需在编译命令加上-lpthread参数即可。

案例演示1:

编写一个程序,使用pthread_create函数创建一个线程,在新创建的线程中打印一个字符串,在主线程中也打印一个字符串。详细代码如下所示:
 

#include <stdio.h>
#include <pthread.h>
void *printString(void *arg)
{printf("This is My first thread\n");return NULL;
}
int main()
{pthread_t thread;int ret = pthread_create(&thread, NULL, printString, NULL);if(ret != 0){printf("创建线程失败\n");return -1;}sleep(1);printf("This is main thread\n");return 0;
}

将以上代码保存为createThread.c文件,编译执行。可以看到新创建的线程被调用成功。

案例演示2:

编写一个程序,使用pthread_create函数创建两个线程,并在每个线程中接受主线程传来的字符串,并将其打印出来。详细代码如下所示:
 

#include <stdio.h>
#include <pthread.h>
void *printString(void *arg)
{printf("print String: %s\n", (char *)arg);return NULL;
}
int main()
{pthread_t thread1, thread2;int ret = pthread_create(&thread1, NULL, printString, "This is first thread");if(ret != 0){printf("创建线程失败\n");return -1;}ret = pthread_create(&thread2, NULL, printString, "This is second thread");if(ret != 0){printf("创建线程失败\n");return -1;}sleep(1);printf("This is main thread\n");return 0;
}

将以上代码保存为printThread.c文件,编译执行。可以看到新创建的按照主线程传递的参数,将指定的字符串打印出来。

注意:编译程序的时候需要手动加上线程库-lpthread。否则,编译时会出错。

编程要求

本关的编程任务是补全右侧代码片段中BeginEnd中间的代码,具体要求如下:

补全createThread函数,使用pthread_create函数创建线程,并将start_routine作为线程处理函数,arg作为线程处理函数的参数,同时将创建成功的线程ID作为createThread函数的返回值。

答案:
#include <stdio.h>
#include <pthread.h>/************************* 参数start_routine: 函数指针,用于指向线程函数* 参数arg: 是线程函数的参数* 返回值: 返回线程ID
*************************/
pthread_t createThread(void *(*start_routine) (void *), void *arg)
{pthread_t thread;/********** BEGIN **********/int res = pthread_create(&thread, NULL, start_routine, arg);if (res != 0){return 0;}/********** END **********/return thread;
}

第2关:线程挂起

任务描述

在学习多进程编程的时候,我们学习了如何等待一个进程结束,那么在多线程中也存在同样的操作,如何使得一个线程挂起等待其他的线程先执行。本关我们将介绍如何挂起一个线程,并等待指定线程。

本关任务:学会使用C语言在Linux系统中使用pthread_join库函数挂起当前线程,并等待指定的线程。

相关知识

通过上一管卡的学习,我们学会了如何创建一个线程。在上一关中我们遗留了一个未解决的问题,不知道细心的你发现没,那就是我们在案例演示中使用了sleep函数给主线程睡眠了1秒,如果主线程先退出,那么新创建的线程会发生什么?正确答案是,如果主线程先退出,那么还未执行完成的其他所有线程将被终止。因此,保证主线程最后一个退出是非常重要的。

接下来,我们用实例验证如果主线程先退出,那么其他的线程会不会受到影响,将上一关中的案例一修改成如下:

#include <stdio.h>
#include <pthread.h>
void *printString(void *arg)
{sleep(1);printf("This is My first thread\n");return NULL;
}
int main()
{pthread_t thread;int ret = pthread_create(&thread, NULL, printString, NULL);if(ret != 0){printf("创建线程失败\n");return -1;}printf("This is main thread\n");return 0;
}

编译执行。可以看到当主线程退出后,新创建的线程是不会继续执行的。

Linux系统中提供了挂起当前线程,用来等待一个指定线程结束的库函数pthread_join。这个函数相当于进程等待函数waitpid,他可以挂起当前线程,并一直等待指定线程,直到指定线程退出后,该函数才会返回继续执行。

Linux系统中,我们可以通过pthread_join函数来挂起线程。我们可以使用man命令来查询该函数的使用方法。具体的查询命令为:man 3 pthread_join

使用pthread_join挂起线程

pthread_join函数的具体的说明如下:

需要的头文件如下:

#include <pthread.h>

函数格式如下:

int pthread_join(pthread_t thread, void **retval);

参数说明:

thread:该参数是一个线程ID,用于指定要等待其终止的线程;
retval:该参数用于存放等待线程的返回值,如果不关注线程的退出值,则可以设置为NULL;

函数返回值说明: 调用成功,pthread_join返回值为0;调用失败返回一个非零的值。

注意:

由于线程是第三库所提供的,因此在编译包含线程操作的程序时,我们需要手动链接线程库,只需在编译命令加上-lpthread参数即可。

案例演示1:

编写一个程序,使用pthread_join函数挂起当前线程,等待新创建的线程先执行。详细代码如下所示:

#include <stdio.h>
#include <pthread.h>
void *printString(void *arg)
{sleep(1);printf("This is My first thread\n");return NULL;
}
int main()
{pthread_t thread;int ret = pthread_create(&thread, NULL, printString, NULL);if(ret != 0){printf("创建线程失败\n");return -1;}if(pthread_join(thread, NULL) != 0){printf("等待线程失败\n");return -1;}printf("This is main thread\n");return 0;
}

将以上代码保存为joinThread.c文件,编译执行。可以看到尽管新创建的线程睡眠了1秒,然后还是被正常的运行完。 注意:编译程序的时候需要手动加上线程库-lpthread。否则,编译时会出错。

编程要求

本关的编程任务是补全右侧代码片段中BeginEnd中间的代码,具体要求如下:

补全waitThread函数,使用pthread_join函数挂起当前线程,等待指定线程结束,thread为要等待的线程ID号,waitThread函数等待线程成功返回0,失败返回-1

答案:
#include <stdio.h>
#include <pthread.h>/************************* 参数thread: 需要等待结束的线程ID号* 返回值: 等待成功返回0,失败返回-1* 提示: 忽略线程返回值
*************************/
int waitThread(pthread_t thread)
{int ret = -1;/********** BEGIN **********/ret = pthread_join(thread, NULL);/********** END **********/return ret;
}

第3关:线程终止

 

任务描述

在学习多进程编程的时候,我们知道进程的退出有很多中方式,常见的有exit函数,而线程的退出也有多种方法。本关我们将介绍如何终止一个线程的执行。

本关任务:学会使用C语言在Linux系统中终止一个线程。

相关知识

Linux下有三种方式可以是一个线程终止,分别是:(1)通过return从线程函数返回;(2)通过调用pthread_exit使得一个线程退出;(3)通过调用pthread_cancel终止一个线程;

有两种特殊情况要注意:第一种情况就是,在主线程中,如果从main函数返回或者是调用exit函数来终止主线程的执行,则整个进程将终止执行,此时进程中的所有线程也将被终止执行,因此,在主线程中不能过早的退出,这就是我们上一关中所介绍的为什么要使用pthread_join函数来挂起主线程的原因。另一种情况就是,如果在主线程中调用pthread_exit函数终止主线程的执行,则仅仅是主线程消亡,进程是不会被终止的,因此进程内的其他线程也不会被终止,直到所有线程执行结束,进程才会被终止。

在上一关中,我们学习了pthread_join函数等待一个线程的结束,并获取线程退出值,那么线程以不同的方法终止,通过pthread_join得到的退出值也是不同的,总结如下:
 

如果线程通过调用return返回,则pthread_join所得到的退出值就是线程函数的return的值;
如果线程是通过调用pthread_cancel异常终止,则pthread_join所得到的退出值是PTHREAD_CANCELED;
如果线程是通过调用pthread_exit异常终止,则pthread_join所得到的退出值就是pthread_exit函数的参数值;

我们可以使用man命令来查询这些函数的使用方法。具体的查询命令为:man 3 函数名

使用pthread_exit退出线程

pthread_exit函数的具体的说明如下:

需要的头文件如下:

#include <pthread.h>

函数格式如下:

void pthread_exit(void *retval);

参数说明:

retval:线程的返回值;

函数返回值说明: 无返回值。

注意:

由于线程是第三库所提供的,因此在编译包含线程操作的程序时,我们需要手动链接线程库,只需在编译命令加上-lpthread参数即可。

案例演示1:

编写一个程序,使用pthread_exit函数退出线程,并使用pthread_join函数获取线程的退出值。详细代码如下所示:

#include <stdio.h>
#include <pthread.h>
void *printString(void *arg)
{sleep(1);printf("This is My first thread\n");pthread_exit("thread finished");
}
int main()
{pthread_t thread;int ret = pthread_create(&thread, NULL, printString, NULL);if(ret != 0){printf("创建线程失败\n");return -1;}void *status = NULL;if(pthread_join(thread, &status) != 0){printf("等待线程失败\n");return -1;}printf("first thread exit(%s)\n", (char *)status);printf("This is main thread\n");return 0;
}

将以上代码保存为exitThread.c文件,编译执行。可以看到新创建的线程退出的代码为:"thread finished",并且在主线程中使用pthread_join函数成功的获取到退出代码。 注意:编译程序的时候需要手动加上线程库-lpthread。否则,编译时会出错。

使用pthread_cancel退出线程

pthread_cancel函数的具体的说明如下:

需要的头文件如下:

#include <pthread.h>

函数格式如下:

int pthread_cancel(pthread_t thread);

参数说明:

thread:需要被取消运行的线程ID;

函数返回值说明: 调用成功,返回0,调用失败,返回一个非零值。

注意:

由于线程是第三库所提供的,因此在编译包含线程操作的程序时,我们需要手动链接线程库,只需在编译命令加上-lpthread参数即可。

案例演示1:

编写一个程序,使用pthread_cancel函数退出线程,并使用pthread_join函数获取线程的退出值。详细代码如下所示:

#include <stdio.h>
#include <pthread.h>
void *printString(void *arg)
{while(1){printf("This is My first thread\n");sleep(1);}
}
int main()
{pthread_t thread;int ret = pthread_create(&thread, NULL, printString, NULL);if(ret != 0){printf("创建线程失败\n");return -1;}sleep(2);ret = pthread_cancel(thread);if(ret != 0){printf("cancel thread(%lu) failure\n", thread);return -1;}void *status = NULL;if(pthread_join(thread, &status) != 0){printf("等待线程失败\n");return -1;}printf("first thread exit(%d)\n", (int)status);printf("This is main thread\n");return 0;
}

将以上代码保存为cancelThread.c文件,编译执行。可以看到新创建的线程被主线程使用pthread_cancel函数强制取消执行,并且退出的代码为:-1,也就是PTHREAD_CANCELED在Linux系统中的定义为-1

注意:

编译程序的时候需要手动加上线程库-lpthread。否则,编译时会出错。

编程要求

本关的编程任务是补全右侧代码片段中BeginEnd中间的代码,具体要求如下:

补全cancelThread函数,使用pthread_cancel函数终止指定的线程,thread为线程要被取消的线程ID号,调用成功返回0,否则返回-1

答案: 
#include <stdio.h>
#include <pthread.h>/************************* 参数thread: 需要等待结束的线程ID号* 返回值: 等待成功返回0,失败返回-1* 提示: 忽略线程返回值
*************************/
int cancelThread(pthread_t thread)
{int ret = -1;/********** BEGIN **********/ret = pthread_cancel(thread);/********** END **********/return ret;
}

相关文章:

Linux之线程管理

目录 第1关&#xff1a;创建线程 任务描述 相关知识 使用pthread_create函数创建线程 编程要求 答案&#xff1a; 第2关&#xff1a;线程挂起 任务描述 相关知识 使用pthread_join挂起线程 编程要求 答案&#xff1a; 第3关&#xff1a;线程终止 任务描述 相关知识 使用pthread…...

.net反射(Reflection)

文章目录 一.概念&#xff1a;二.反射的作用&#xff1a;三.代码案例&#xff1a;四.运行结果&#xff1a; 一.概念&#xff1a; .NET 反射&#xff08;Reflection&#xff09;是指在运行时动态地检查、访问和修改程序集中的类型、成员和对象的能力。通过反射&#xff0c;你可…...

白平衡简介

文章目录 白平衡的概念白平衡的调节常见的白平衡模式 白平衡的概念 白平衡是指摄影、摄像和显示技术中的一项重要概念&#xff0c;用于调节图像中的白色或中性灰色的色彩&#xff0c;使其看起来在不同光源条件下都是准确的白色或灰色。白平衡的主要目的是确保图像的色彩准确性…...

centos7.9下安装SVN服务

一、安装subversion yum install -y subversion #安装svn mkdir -p /data/svnrepos/java #自定义svn仓库位置/data/svnrepos&#xff0c;自定义一个项目叫svn&#xff08;这里新建目录&#xff09; svnadmin create /data/svnrepos/java #创建一…...

iStat Menus for Mac:强大的系统监控工具

iStat Menus for Mac是一款功能强大的系统监控工具&#xff0c;专为Mac用户设计&#xff0c;旨在帮助用户全面了解电脑的运行状态&#xff0c;提高电脑的性能和稳定性。 iStat Menus for Mac v6.73 (1239)中文版下载 该软件可以实时监测CPU使用率、内存占用、网络速度、硬盘活动…...

NumPy 1.26 中文官方指南(四)

附加文件 术语表 原文&#xff1a;numpy.org/doc/1.26/glossary.html (n,) 括号中跟着逗号的数字表示一个具有一个元素的元组。尾随逗号将一个元素元组与括号n区分开。 -1 在维度入口中&#xff0c;指示 NumPy 选择长度&#xff0c;以保持数组元素总数不变。 >>> n…...

Python flask

Flask 是一个用 Python 编写的轻量级 Web 应用框架。它被设计为易于使用和扩展&#xff0c;使其成为构建简单网站到复杂的、动态的 web 应用程序的理想选择。以下是 Flask 的一些基本组件和概念&#xff1a; 主要组件 Flask&#xff1a;框架本身&#xff0c;提供基本的功能来处…...

2-token生成

Token是密码学中的一个概念&#xff0c;可以用作身份验证凭证。在计算机领域中&#xff0c;token可以是一个字符串&#xff0c;用于标识用户的身份和权限。当用户进行身份验证时&#xff0c;他们通常会收到一个token&#xff0c;以便在将来的请求中用作凭证。 在互联网应用程序…...

Flutter 上架如何解决 ITMS-91053 问题

最近&#xff0c;我的 Flutter App 发布到 TestFlight 后&#xff0c;就会收到一封邮件&#xff1a;The uploaded build for YOUR APP has one or more issues. 上面的邮件主要是说&#xff0c;我的 App 缺少了调用 API 的声明&#xff0c;以前从来没看到过&#xff0c;上网一查…...

PgSQL的登录相关(Ubuntu22.04)

一 将用户设为密码登录方式 1 修改用户的密码 sudo -u postgres psql -c "ALTER USER yuhui WITH PASSWORD xinmima;" 2 修改配置&#xff0c;指定用户yuhui使用密码登录 sudo vi /etc/postgresql/16/main/pg_hba.conf local all postgres …...

ThingsBoard处理设备上报的属性并转换为可读属性

一、前言 二、案例 1、AI生成JSON数据体 2、将json数据体直接通过遥测topic发送查看效果 3、可查看目前整个数据都在一起 ​编辑 4、配置附规则链路 5、对msg的消息值&#xff0c;进行数据的转换&#xff0c;并从新进行赋值。 6、规则链路关联关系 7、再次通过MQTT发送遥…...

03-JAVA设计模式

设计模式GOF23 GOF23是指由设计模式经典名著《Design Patterns: Elements of Reusable Object-Oriented Software》&#xff08;中译本名为《设计模式——可复用面向对象软件的基础》&#xff09;的四位作者Erich Gamma、Richard Helm、Ralph Johnson、以及John Vlissides提出…...

Aws Nat Gateway

要点 NAT网关要能访问外网&#xff0c;所以需要部署在有互联网网关的Public子网中。 关键&#xff1a; NAT网关创建是选择子网&#xff0c;一定要选择公有子网&#xff08;有互联网网关子网&#xff09; 特别注意&#xff1a; 新建nat网关的时候&#xff0c;选择的子网一定…...

SLICEM是如何将查找表配置为分布式RAM/移位寄存器的

1.首先说SliceM和SliceL如何配置为ROM的 一个SLICE包含4个六输入查找表&#xff0c;因此每个查找表就能存储64bit的数据&#xff0c;要实现128bit的ROM&#xff0c;只需要通过两个LUT就可实现&#xff0c;具体如下表: 2.如何配置成为分布式RAM SLICEM中的LUT如下图&#xff…...

Echarts-知识图谱

Echarts-知识图谱 demo地址 打开CodePen 效果 思路 1. 生成根节点 2. 根据子节点距离与根节点的角度关系&#xff0c;生成子节点坐标&#xff0c;进而生成子节点 3. 从子节点上按角度生成对应的子节点 4. 递归将根节点与每一层级子节点连线核心代码 定义节点配置 functio…...

Scala 05 —— 函数式编程底层逻辑

Scala 05 —— 函数式编程底层逻辑 该文章来自2023/1/14的清华大学交叉信息学院助理教授——袁洋演讲。 文章目录 Scala 05 —— 函数式编程底层逻辑函数式编程假如...副作用是必须的&#xff1f;函数的定义函数是数据的函数&#xff0c;不是数字的函数如何把业务逻辑做成纯函…...

在 Node.js 中配置代理 IP 采集文章

不说废话&#xff0c;直接上代码&#xff1a; const http require(http); const https require(https);// 之后可以使用 http 或 https 模块发起请求&#xff0c;它们将自动使用配置的代理 // 代理ip&#xff1a;https://www.kuaidaili.com/?refrg3jlsko0ymg const proxy …...

ESLlint重大更新后,使用旧版ESLint搭配Prettier的配置方式

概要 就在前几天&#xff0c;ESLint迎来了一次重大更新&#xff0c;9.0.0版本&#xff0c;根据官方文档介绍&#xff0c;使用新版的先决条件是Node.js版本必须是18.18.0、20.9.0&#xff0c;或者是>21.1.0的版本&#xff0c;新版ESLint将不再直接支持以下旧版配置(非扁平化…...

springcloud Ribbon的详解

1、Ribbon是什么 Ribbon是Netflix发布的开源项目&#xff0c;Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的框架。 2、Ribbon能干什么 LB负载均衡(Load Balance)是什么&#xff1f;简单的说就是将用户的请求平摊的分配到多个服务上&#xff0c;从而达…...

超级好用的C++实用库之Des加解密

概述 DES&#xff08;Data Encryption Standard&#xff0c;数据加密标准&#xff09;是一种历史悠久的对称密钥加密算法&#xff0c;由IBM公司在1970年代设计&#xff0c;并于1977年被美国国家标准局选作联邦资料处理标准。DES使用56位密钥对64位的数据块进行操作&#xff0c;…...

关于MCU核心板的一些常见问题

BGA植球与焊接&#xff08;多涂焊油&#xff09;&#xff1a; 【BGA芯片是真麻烦&#xff0c;主要是植锡珠太麻烦了&#xff0c;拆一次就得重新植】https://www.bilibili.com/video/BV1vW4y1w7oNvd_source3cc3c07b09206097d0d8b0aefdf07958 / NC电容一般有两种含义&#xff1…...

【C++杂货铺】多态

目录 &#x1f308;前言&#x1f308; &#x1f4c1;多态的概念 &#x1f4c1; 多态的定义及实现 &#x1f4c2; 多态的构成条件 &#x1f4c2; 虚函数 &#x1f4c2; 虚函数重写 &#x1f4c2; C11 override 和 final &#x1f4c2; 重载&#xff0c;覆盖&#xff08;重写…...

(学习日记)2024.04.20:UCOSIII第四十八节:各文件功能概览

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…...

数据结构-二叉树-堆(二)

一、建堆的时间复杂度问题 1、除了向上调整建堆&#xff0c;我们还可以向下调整建堆。不能在根上直接开始向下调整。这里的条件就是左右子树必须都是大堆或者小堆。我们可以倒着往前走&#xff0c;可以从最后一个叶子开始调整。但是从叶子开始调整没有意义。所以我们可以从倒数…...

身份证二要素核验介绍及使用方法

一、身份证二要素核验简介及重要性 身份证二要素核验是一种重要的身份验证技术&#xff0c;它在现代社会中发挥着至关重要的作用&#xff0c;特别是在涉及个人信息安全和隐私保护的领域。通过身份证二要素核验&#xff0c;我们可以有效地确认个人身份的真实性&#xff0c;从而…...

探索 去中心化的Web3.0

随着区块链技术的日益成熟和普及&#xff0c;Web3&#xff08;Web 3.0&#xff09;已经成为一个无法忽视的趋势。Web3不仅仅是一个技术概念&#xff0c;更是一个去中心化、透明、用户数据拥有权归还给用户的互联网新时代。在这篇文章中&#xff0c;我们将深入探讨Web3技术的核心…...

递归的层序遍历

最近遇到一个业务需求&#xff1a;一颗依赖树&#xff0c;其实就是一颗递归树&#xff0c;如何一层一层的数据放在一起&#xff0c;可以近似理解为二叉树的层序遍历。 业务理解为递归树的层序遍历 代码示例&#xff1a; public class RecursionErgodic {public static void…...

pytest使用 pytest-rerunfailures 插件实现失败用例重跑功能

使用 pytest 进行测试时&#xff0c;你可以通过安装并配置 pytest-rerunfailures 插件来实现失败用例重跑功能。以下是一个示例说明&#xff1a; 假设你有一个测试文件 test_example.py 包含如下测试用例&#xff1a; import pytestpytest.mark.parametrize("num",…...

2024/4/23 C++day1

有以下定义&#xff0c;说明哪些量可以改变哪些不可以改变&#xff1f; const char *p; 指针可以改变 值不可以改变 const (char *) p; 语法错误 char *const p; 指针不可以改变 值可以改变 const char* const p; 指针和值…...

OpenHarmony鸿蒙南向开发案例:【智能窗户通风设备】

样例简介 本文档介绍了安全厨房案例中的相关智能窗户通风设备&#xff0c;本安全厨房案例利用轻量级软总线能力&#xff0c;将两块欧智通V200Z-R/BES2600开发板模拟的智能窗户通风设备和燃气告警设备组合成。当燃气数值告警时&#xff0c;无需其它操作&#xff0c;直接通知软总…...

解析‘找不到vcruntime140.dll,无法继续执行代码’的异常修复方法

找不到vcruntime140.dll,无法继续执行代码&#xff1f;这是小事情&#xff0c;这个情况主要是vcruntime140.dll文件丢失了&#xff0c;导致一些程序没办法正常的运行&#xff0c;我们只要修复好这个vcruntime140.dll,文件就可以了。下面一起来了解一下。 一.找不到vcruntime140…...

Golang对接Ldap(保姆级教程:概念搭建实战)

Golang对接Ldap&#xff08;保姆级教程&#xff1a;概念&搭建&实战&#xff09; 最近项目需要对接客户的LDAP服务&#xff0c;于是趁机好好了解了一下。LDAP实际是一个协议&#xff0c;对应的实现&#xff0c;大家可以理解为一个轻量级数据库。用户查询。比如&#xff…...

Java23种设计模式-创建型模式之工厂方法模式

工厂方法模式&#xff08;Factory Method Pattern&#xff09; 一种创建型设计模式&#xff0c;它定义了一个用于创建对象的接口&#xff0c;让子类决定将哪一个类实例化&#xff0c;从而将产品的实例化推迟到子类中。这种模式的主要角色包括&#xff1a; 角色1&#xff1a;抽…...

Oracle故障处理:ORA-00600错误处理思路

提前说明&#xff1a; 该故障&#xff0c;我只是旁观者。 但处理该故障的DBA工程师&#xff0c;思路很清晰&#xff0c;我非常受教&#xff01;在此也将经验分享。 目录 项目场景 问题分析 优化建议 项目场景 在某项目数据库运维群&#xff0c;有现场同事发了张报错截图如下…...

微信小程序使用 Vant Weapp 中 Collapse 折叠面板 的问题!

需求&#xff1a;结合Tab 标签页 和 Collapse 折叠面板 组合成显示课本和章节内容&#xff0c;并且用户体验要好点&#xff01; 如下图展示&#xff1a; 问题&#xff1a;如何使用Collapse 折叠面板 将内容循环展示出来&#xff1f; js中的数据是这样的 代码实现&#xff1…...

论文写作神器:用ChatGPT写论文的5大高效技巧

在人工智能日渐成熟的今天&#xff0c;ChatGPT已经成为学术界、业界乃至日常生活中不可或缺的工具之一。尤其是对于学生和研究人员而言&#xff0c;ChatGPT能大幅度提高论文写作的效率和质量。然而&#xff0c;许多人尚未掌握如何高效利用这一工具&#xff0c;很多人用chatgpt写…...

微信小程序展示倒计时

html <view class"countdown"> <text>倒计时&#xff1a;</text> <text wx:for"{{countdown}}" wx:key"index">{{item}}</text> </view> ts data: {countdown: [], // 存放倒计时数组 targetTime:…...

什么是用户体验(UX)文案,为什么它很重要?

网上购物如今比以往任何时候都更加相关。所以我们将以此为例说明什么是用户体验&#xff08;UX&#xff09;文案&#xff0c;以及为什么它很重要。 假设你去了一个在线商店。你需要执行一系列操作&#xff1a; 找到合适的部分选择你感兴趣的产品弄清楚它们是什么&#xff0c;…...

算法06链表

算法06链表 一、链表概述1.1概述1.2链表的组成部分&#xff1a;1.3链表的优缺点&#xff1a; 二、链表典例力扣707.设计链表难点分析&#xff1a;&#xff08;1&#xff09;MyLinkedList成员变量的确定&#xff1a;&#xff08;2&#xff09;初始化自定义链表&#xff1a;&…...

第十七章 数据管理和组织变革管理

17.2 变革法则 1&#xff09;组织不变革&#xff0c;人就变。 2&#xff09;人们不会抗拒变革&#xff0c;但抵制被改变。 3&#xff09;事情之所以存在是惯性所致。 4&#xff09;除非有人推动变革&#xff0c;否则很可能止步不前。 5&#xff09;如果不考虑人的因素&#xf…...

基于harris角点和RANSAC算法的图像拼接matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022a 3.部分核心程序 ....................................................................... I1_harris fu…...

C++感受6-Hello World 交互版

变量、常量输入、输出、流getline() 函数读入整行输入Hello() 函数复习新定义函数 Input() 实现友好的人机交互还有 “痘痘” 为什么挤不到的分析…… 1. DRY 原则简介 上一节课&#xff0c;我们写了两版“问候”程序。第一版的最大问题是重复的内容比较多&#xff0c;每一次问…...

02_c/c++开源库ZeroMQ

1.安装 C库 libzmq sudo apt install libzmq3-dev 实例: https://zeromq.org/get-started/?languagec&librarylibzmq# 编译依赖: pkg-config --cflags --libs libzmq or cat /usr/lib/x86_64-linux-gnu/pkgconfig/libzmq.pc -isystem /usr/include/mit-krb5 -I/usr/in…...

计算机视觉 CV 八股分享 [自用](更新中......)

目录 一、深度学习中解决过拟合方法 二、深度学习中解决欠拟合方法 三、梯度消失和梯度爆炸 解决梯度消失的方法 解决梯度爆炸的方法 四、神经网络权重初始化方法 五、梯度下降法 六、BatchNorm 七、归一化方法 八、卷积 九、池化 十、激活函数 十一、预训练 十二…...

【MHA】MySQL高可用MHA源码1-主库故障监控

1 阅读之前的准备工作 1 一个IDE工具 &#xff0c;博主自己尝试了vscode安装perl的插件&#xff0c;但是函数 、变量 、模块等都不能跳转&#xff0c;阅读起来不是很方便。后来尝试使用了pycharm安装perl插件&#xff0c;阅读支持跳转&#xff0c;自己也能写一些简单的测试样例…...

如何一键清除文件目录下所有的node_modules

如何一键清除文件目录下所有的node_modules 快速删除目录下的node_modules&#xff0c;下面附上windows和mac的脚本指令 windows脚本 FOR /d /r . %d in (node_modules) DO IF EXIST "%d" rm -rf "%d"mac脚本 find . -name "node_modules" -…...

【产品经理修炼之道】- 导航架构设计

目录 一、导航是什么 二、导航的作用 三、导航的分类 四、导航菜单的广度与深度 五、导航的颜色 六、导航的形态 七、导航的研究 八、导航的设计 九、导航改版案例分享 总结 每个网页的设计都需要包括导航&#xff0c;那么导航架构该如何设计&#xff1f;作者结合之前…...

本地部署和运行大型语言模型(Large Language Models, LLMs)的工具Ollama

文章目录 本地部署和运行大型语言模型&#xff08;Large Language Models, LLMs&#xff09;的工具Ollama背景什么是Ollama主要功能优势 使用场景Ollama LangChain 实现本地运行Llama 3 本地部署和运行大型语言模型&#xff08;Large Language Models, LLMs&#xff09;的工具…...

Python-100-Days: Day01

Day01 Python简介 1.1989年Guido von Rossum在圣诞节之夜开始着手python语言编译器的编写。 2.1991年2月 Python v1 编译器诞生&#xff0c;使用C实现的&#xff0c;此时可以调用C的库函数。 3.1994年1月&#xff0c;Python v1.0 正式版发布。 4.2000年10月16日&#xff0…...

g 对象:Flask 应用中的“临时口袋”

文章目录 g对象的理解Flask 中的 g 对象g 对象的特点:使用 g 对象: 示例 g对象的理解 想象一下&#xff0c;你在逛超市。你需要一个购物篮来装你挑选的商品。这个购物篮就像 Flask 应用中的 g 对象&#xff0c;它是一个临时存放东西的地方&#xff0c;方便你在购物过程中随时取…...

start.spring.io不支持java8,idea使用阿里云又报错

做项目的时候&#xff0c;我们可以发现&#xff0c;访问https://start.spring.io/ 创建脚手架项目的时候&#xff0c;最低是java 17了 但是对于很多项目来说&#xff0c;还是在用java8&#xff0c;这该怎么办呢&#xff1f; 值得庆幸的是&#xff0c;阿里云也同样有相同功能的…...

第十六节:图 (20节)

一 图的概念 1&#xff09;由点的集合和边的集合构成 2&#xff09;虽然存在有向图和无向图的概念&#xff0c;但实际上都可以用有向图来表达 3&#xff09;边上可能带有权值 二 图结构的表达 1&#xff09;邻接表法 2&#xff09;邻接矩阵法 3&#xff09;除此之外还有其他众多…...

vue+vant项目0-1快速发布到--钉钉应用

uniapp开发笔记----vue开发项目配置钉钉应用 一、 vuevant开发项目1. 自定义vuevant项目或者已经有的旧项目1. 自定义vuevant项目1. 创建vue项目2. 安装依赖3. 引入所有组件4. 使用一个组件/效果和代码如下&#xff1a; 2. git官网仓库&#xff0c;直接拉默认dome代码3. 打包项…...

(四十二)第 6 章 树和二叉树(树的二叉链表(孩子-兄弟)存储)

1. 背景说明 2. 示例代码 1) errorRecord.h // 记录错误宏定义头文件#ifndef ERROR_RECORD_H #define ERROR_RECORD_H#include <stdio.h> #include <string.h> #include <stdint.h>// 从文件路径中提取文件名 #define FILE_NAME(X) strrchr(X, \\) ? strrch…...

在js中table表格中进行渲染轮播图

效果图&#xff1a;示例&#xff1a; <!DOCTYPE html> <html> <head><meta charset"utf-8"><title></title><script src"js/jquery-3.6.3.js"></script><style>/* 轮播图 */.basko {width: 100%;h…...

Spring MVC(三) 参数传递

1 Controller到View的参数传递 在Spring MVC中&#xff0c;把值从Controller传递到View共有5中操作方法&#xff0c;分别是。 使用HttpServletRequest或HttpSession。使用ModelAndView。使用Map集合使用Model使用ModelMap 使用HttpServletRequest或HttpSession传值 使用HttpSe…...

安防监控视频平台智能边缘分析一体机视频存储系统客流统计检测算法

智能边缘分析一体机的客流统计检测算法是一种基于人工智能与边缘计算技术的解决方案&#xff0c;专门设计用来实时、准确地统计通过特定区域的人流量。这项技术广泛应用于零售、交通、场馆管理、智慧城市等领域&#xff0c;以帮助管理者更好地理解顾客行为、优化资源配置、提升…...

.NET使用Microsoft.IdentityModel.Tokens对SAML2.0登录断言校验

如题。使用SAML单点登录对IDP返回的Response断言使用微软提供的Microsoft.IdentityModel.Tokens对断言&#xff08;Assertion&#xff09;进行校验。 首先需要安装Muget包&#xff0c;Microsoft.IdentityModel.Tokens和Microsoft.IdentityModel.Tokens.Saml。 简易示例代码如…...

【动态规划】子序列问题II|最长定差子序列|最长的斐波那契数列的长度|最长等差数列|等差数列的划分

一、最长定差子序列 1218. 最长定差子序列 算法原理&#xff1a; &#x1f4a1;细节&#xff1a; 1.正常创建dp表&#xff0c;分析状态转移方程&#xff1a;可能b存在于多个不同的位置&#xff0c;那么要用哪个下标的dp呢&#xff1f; 用最后一个b的&#xff0c;因为用前面的可…...

农林科学SCI期刊,IF=6+,影响力高,对国人非常友好!

一、期刊名称 Crop Journal 二、期刊简介概况 期刊类型&#xff1a;SCI 学科领域&#xff1a;农林科学 影响因子&#xff1a;6.6 中科院分区&#xff1a;1区 出版方式&#xff1a;开放出版 版面费&#xff1a;$900 三、期刊征稿范围 《作物杂志》是一份双月刊、国际、同…...

前端学习第一课

AJAX 事先说明&#xff0c;这只是记录&#xff0c;并不是从零到一的教学内容&#xff0c;如果想要学习的话&#xff0c;可以跳过本文章了 ok&#xff0c;转回正题&#xff0c;正如上面所说&#xff0c;这只是记录。其实我是有一定的前端基础的&#xff0c;也做过涉及相关的开发…...

基于SpringBoot设计模式之创建型设计模式·生成器模式

文章目录 介绍开始架构图样例一定义生成器定义具体生成器&#xff08;HTML格式、markdown格式&#xff09;实体类HTML格式生成器MarkDown格式生成器 测试样例 总结优点缺点 介绍 将一个复杂对象的构建与它的表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。   如…...