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

linux——线程

在 Linux 系统中,进程和线程是两种重要的并发执行单元。本文将详细介绍它们的区别、使用场景、以及多线程编程中的关键API和示例代码。

进程与线程的区别

进程

  • 进程是程序运行的一个实例,承担分配系统资源的基本单位。
  • 每个进程都有独立的地址空间,一个进程崩溃不会影响其他进程。
  • 进程的创建和切换消耗较多资源。

线程

  • 线程是进程中的一个执行路径,是CPU调度的基本单位。
  • 线程共享进程的地址空间,但每个线程有自己的堆栈和局部变量。
  • 线程的创建和切换开销较小。
  • 如果一个线程崩溃,会导致整个进程崩溃。

使用线程的理由

  1. 节省资源:创建进程需要分配独立的地址空间,建立多个数据表来维护其代码段、数据段和堆栈段,这种方式十分昂贵。线程共享同一进程的地址空间和大部分数据,启动一个线程比启动一个进程要快很多。一个进程的开销大约是一个线程的30倍。
  2. 方便的通信机制:不同进程之间的数据传递需要通过通信机制,如管道、信号等,这种方式耗时且复杂。而线程共享进程的数据空间,数据共享非常方便和快捷,但需要注意数据同步的问题。

多线程开发及API

多线程开发主要包含三点:线程、互斥锁、条件变量。以下是具体的操作和API介绍:

线程操作

线程的创建
#include <pthread.h>
int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
// 返回:若成功返回0,否则返回错误编号
线程的获取和比较
#include <pthread.h>
pthread_t pthread_self(void);
线程的等待
#include <pthread.h>
int pthread_join(pthread_t thread, void **rval_ptr);
// 参数:
// pthread_t thread:等待的线程
// void **rval:线程退出状态的收回,NULL表示不收回
线程的退出
#include <pthread.h>
int pthread_exit(void *rval_ptr);

线程的创建、退出、等待示例

#include <stdio.h>
#include <pthread.h>void *func1(void *arg)
{static int ret = 10;printf("t1:%ld thread is created\n", (unsigned long)pthread_self());printf("t1: parameter is %d\n", *((int *)arg));pthread_exit((void*)&ret); // 线程退出
}int main()
{int ret;int param = 100;int *pret = NULL;pthread_t t1;ret = pthread_create(&t1, NULL, func1, (void*)&param); // 创建线程if(ret == 0){printf("main: create t1 success\n");}printf("main: %ld\n", (unsigned long)pthread_self()); // 获取线程IDpthread_join(t1, (void**)&pret); // 等待线程退出printf("main: t1 quit with %d\n", *pret);return 0;
}

传入一个结构体的线程创建示例

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>struct data
{int a;char *s;
};void *func1(void *arg)
{static char *x = "t1 run out";struct data *temp;temp = (struct data*)arg;printf("t1:%ld pthread is created\n", (unsigned long)pthread_self());printf("t1: %d\n", temp->a);printf("t1: %s\n", temp->s);pthread_exit((void*)x);
}int main()
{int ret;pthread_t t1;char *pret = NULL;struct data *p = (struct data*)malloc(sizeof(struct data));p->a = 1;p->s = "xiancheng";ret = pthread_create(&t1, NULL, func1, (void*)p);if(ret == 0){printf("main: create t1 success\n");}printf("main: %ld\n", (unsigned long)pthread_self());pthread_join(t1, (void**)&pret);printf("main: t1 quit with %s\n", pret);free(p);return 0;
}

线程共享空间验证示例

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>int g_data = 10;void *func1(void *arg)
{printf("t1:%ld thread is created\n", (unsigned long)pthread_self());printf("t1: parameter is %d\n", *((int*)arg));while(1){printf("%d\n", g_data++);sleep(1);if(g_data == 3){pthread_exit(NULL);}}
}void *func2(void *arg)
{printf("t2:%ld thread is created\n", (unsigned long)pthread_self());printf("t2: parameter is %d\n", *((int*)arg));while(1){printf("%d\n", g_data++);sleep(1);}
}int main()
{int ret;int param = 100;pthread_t t1;pthread_t t2;ret = pthread_create(&t1, NULL, func1, (void*)&param);if(ret == 0){printf("main: create t1 success\n");}ret = pthread_create(&t2, NULL, func2, (void*)&param);if(ret == 0){printf("main: create t2 success\n");}printf("main: %ld\n", (unsigned long)pthread_self());while(1){printf("%d\n", g_data++);sleep(1);} pthread_join(t1, NULL);pthread_join(t2, NULL);return 0;
}

互斥锁(Mutex)

互斥锁API
创建及销毁互斥锁
#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
int pthread_mutex_destroy(pthread_mutex_t *restrict mutex);
加锁及解锁
#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *restrict mutex);
int pthread_mutex_trylock(pthread_mutex_t *restrict mutex);
int pthread_mutex_unlock(pthread_mutex_t *restrict mutex);

使用互斥锁的示例

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>int g_data = 0;
pthread_mutex_t mutex; // 定义锁void *func1(void *arg)
{pthread_mutex_lock(&mutex); // 加锁for(int i = 0; i < 5; i++){printf("t1: %ld thread is created\n", (unsigned long)pthread_self());printf("t1: parameter is %d\n", *((int*)arg));sleep(1);}pthread_mutex_unlock(&mutex); // 解锁
}void *func2(void *arg)
{pthread_mutex_lock(&mutex);for(int i = 0; i < 5; i++){printf("t2: %ld thread is created\n", (unsigned long)pthread_self());printf("t2: parameter is %d\n", *((int*)arg));sleep(1);}pthread_mutex_unlock(&mutex);
}void *func3(void *arg)
{pthread_mutex_lock(&mutex);for(int i = 0; i < 5; i++){printf("t3: %ld thread is created\n", (unsigned long)pthread_self());printf("t3: parameter is %d\n", *((int*)arg));sleep(1);}pthread_mutex_unlock(&mutex);
}int main()
{int ret;int param = 100;pthread_t t1;pthread_t t2;pthread_t t3;pthread_mutex_init(&mutex, NULL); // 初始化锁ret = pthread_create(&t1, NULL, func1, (void*)&param);if(ret == 0){printf("main: create t1 success\n");}ret = pthread_create(&t2, NULL, func2, (void*)&param);if(ret == 0){printf("main: create t2 success\n");}ret = pthread_create(&t3, NULL, func3, (void*)&param);if(ret == 0){printf("main: create t3 success\n");}printf("main: %ld\n", (unsigned long)pthread_self());pthread_join(t1, NULL);pthread_join(t2, NULL);pthread_join(t3, NULL);pthread_mutex_destroy(&mutex); // 收回锁return 0;
}

互斥锁限制共享资源的访问示例

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>int g_data = 0;
pthread_mutex_t mutex;void *func1(void *arg)
{printf("t1: %ld pthread is created\n", (unsigned long)pthread_self());printf("t1: parameter is %d\n", *((int*)arg));while(1){pthread_mutex_lock(&mutex);printf("%d\n", g_data++);sleep(1);if(g_data == 3){pthread_mutex_unlock(&mutex);pthread_exit(NULL);}}
}void *func2(void *arg)
{printf("t2: %ld pthread is created\n", (unsigned long)pthread_self());printf("t2: parameter is %d\n", *((int*)arg));while(1){printf("%d\n", g_data);pthread_mutex_lock(&mutex);g_data++;pthread_mutex_unlock(&mutex);sleep(1); }
}int main()
{int ret;int param = 100;pthread_t t1;pthread_t t2;pthread_mutex_init(&mutex, NULL);ret = pthread_create(&t1, NULL, func1, (void*)&param);if(ret == 0){printf("main: create t1 success\n");}ret = pthread_create(&t2, NULL, func2, (void*)&param);if(ret == 0){printf("main: create t2 success\n");}printf("main: %ld\n", (unsigned long)pthread_self());pthread_join(t1, NULL);pthread_join(t2, NULL);pthread_mutex_destroy(&mutex);return 0;
}

死锁示例

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>pthread_mutex_t mutex;
pthread_mutex_t mutex2;void *func1(void *arg)
{pthread_mutex_lock(&mutex);sleep(1);pthread_mutex_lock(&mutex2);for(int i = 0; i < 5; i++){printf("t1: %ld\n", (unsigned long)pthread_self());printf("t1: parameter is %d\n", *((int *)arg));sleep(1);}pthread_mutex_unlock(&mutex);pthread_mutex_unlock(&mutex2);
}void *func2(void *arg)
{pthread_mutex_lock(&mutex2);sleep(1);pthread_mutex_lock(&mutex);for(int i = 0; i < 5; i++){printf("t2: %ld\n", (unsigned long)pthread_self());printf("t2: parameter is %d\n", *((int *)arg));sleep(1);}pthread_mutex_unlock(&mutex2);pthread_mutex_unlock(&mutex);
}void *func3(void *arg)
{pthread_mutex_lock(&mutex);for(int i = 0; i < 5; i++){printf("t3: %ld\n", (unsigned long)pthread_self());printf("t3: parameter is %d\n", *((int *)arg));sleep(1);}pthread_mutex_unlock(&mutex);
}int main()
{int ret;int param = 100;pthread_t t1;pthread_t t2;pthread_t t3;pthread_mutex_init(&mutex, NULL);pthread_mutex_init(&mutex2, NULL);ret = pthread_create(&t1, NULL, func1, (void*)&param);if(ret == 0){printf("main: create t1 success\n");}ret = pthread_create(&t2, NULL, func2, (void*)&param);if(ret == 0){printf("main: create t2 success\n");}ret = pthread_create(&t3, NULL, func3, (void*)&param);if(ret == 0){printf("main: create t3 success\n");}printf("main: %ld\n", (unsigned long)pthread_self());pthread_join(t1, NULL);pthread_join(t2, NULL);pthread_join(t3, NULL);pthread_mutex_destroy(&mutex);pthread_mutex_destroy(&mutex2);return 0;
}

条件变量实现线程同步

条件变量API
创建及销毁条件变量
#include <pthread.h>
int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
int pthread_cond_destroy(pthread_cond_t cond);
等待
#include <pthread.h>
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict timeout);
触发
#include <pthread.h>
int pthread_cond_signal(pthread_cond_t *restrict cond);
int pthread_cond_broadcast(pthread_cond_t cond);

使用条件变量的示例

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>int g_data = 0;
pthread_mutex_t mutex;
pthread_cond_t cond;void *func1(void *arg)
{static int cnt = 10;printf("t1: %ld pthread is created\n", (unsigned long)pthread_self());printf("t1: parameter is %d\n", *((int*)arg));while(1){pthread_cond_wait(&cond, &mutex); // 等待if(g_data == 3){printf("t1 run=========================\n");}printf("t1: %d\n", g_data);g_data = 0;sleep(1);if(cnt++ == 10){exit(1);}}
}void *func2(void *arg)
{printf("t2: %ld pthread is created\n", (unsigned long)pthread_self());printf("t2: parameter is %d\n", *((int*)arg));while(1){printf("t2: %d\n", g_data);pthread_mutex_lock(&mutex);printf("%d\n", g_data++);if(g_data == 3){pthread_cond_signal(&cond); // 触发}pthread_mutex_unlock(&mutex);sleep(1);}
}int main()
{int ret;int param = 100;pthread_t t1;pthread_t t2;pthread_cond_init(&cond, NULL);pthread_mutex_init(&mutex, NULL);ret = pthread_create(&t1, NULL, func1, (void *)&param);if(ret == 0){printf("main: create t1 success\n");}ret = pthread_create(&t2, NULL, func2, (void *)&param);if(ret == 0){printf("main: create t2 success\n");}pthread_join(t1, NULL);pthread_join(t2, NULL);pthread_mutex_destroy(&mutex);pthread_cond_destroy(&cond);return 0;
}

通过上述示例和API的讲解,本文详细介绍了Linux下进程与线程的区别、多线程开发的基本操作以及常见问题和解决方案。希望能够帮助大家更好地理解和使用多线程编程。

相关文章:

linux——线程

在 Linux 系统中&#xff0c;进程和线程是两种重要的并发执行单元。本文将详细介绍它们的区别、使用场景、以及多线程编程中的关键API和示例代码。 进程与线程的区别 进程 进程是程序运行的一个实例&#xff0c;承担分配系统资源的基本单位。每个进程都有独立的地址空间&…...

install nebula with source

linux 环境&#xff1a;ubuntu 2004 默认gcc 7.5 nebula requerment&#xff1a; g 8.5 above 下载source git clone --branch release-3.8 https://github.com/vesoft-inc/nebula.git install gcc g 11 apt install gcc-11 g-11 此时 linux环境存在多个版本gcc&#xff1a…...

拆分盘投资策略解析:机制、案例与风险考量

一、引言 随着互联网技术的迅猛发展和金融市场的不断创新&#xff0c;拆分盘这一投资模式逐渐崭露头角&#xff0c;成为投资者关注的焦点。它基于特定的拆分策略&#xff0c;通过调整投资者持有的份额和单价&#xff0c;实现了看似稳健的资产增长。本文旨在深入探讨拆分盘的运…...

Redis主从复制、哨兵模式以及Cluster集群

一.主从复制 1.主从复制的概念 主从复制&#xff0c;是指将一台Redis服务器的数据&#xff0c;复制到其他的Redis服务器。前者称为主节点(Master)&#xff0c;后者称为从节点(Slave)&#xff1b;数据的复制是单向的&#xff0c;只能由主节点到从节点。默认情况下&#xff0c;…...

【chatgpt】npy文件和npz文件区别

npy文件和npz文件都是用于存储NumPy数组的文件格式。它们的主要区别如下&#xff1a; npy文件&#xff1a;这种文件格式用于存储单个NumPy数组。它是一种简单的二进制文件格式&#xff0c;可以快速地读写NumPy数组。 npz文件&#xff1a;这种文件格式是一个压缩包&#xff0c;…...

为什么IP地址会被列入黑名单?

您是否曾经历过网站访客数量骤减或电子邮件投递失败的困扰&#xff1f;这背后或许隐藏着一个常被忽略的原因&#xff1a;您的IP地址可能已经被列入了黑名单内。尽管您并没有进行任何违法的网络操作&#xff0c;但这个问题依然可能出现。那么&#xff0c;究竟黑名单是什么&#…...

【OceanBase诊断调优】—— 如何查找表被哪些其它表引用外键

本文详述如何查找指定表是否被其他表引用做外键。 适用版本 OceanBase 数据库所有版本。 MySQL 租户 obclient> select * from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where REFERENCED_TABLE_NAME表名;Oracle 租户 obclient> SELECT TABLE_NAME FROM dba_constraint…...

网络编程常见问题

1、TCP状态迁移图 2、TCP三次握手过程 2.1、握手流程 1、TCP服务器进程先创建传输控制块TCB&#xff0c;时刻准备接受客户进程的连接请求&#xff0c;此时服务器就进入了LISTEN&#xff08;监听&#xff09;状态&#xff1b; 2、TCP客户进程也是先创建传输控制块TCB&#xff…...

回调函数的使用详解

实际工作中&#xff0c;经常使用回调函数。用来实现触发等机制&#xff0c;也是基于一些已开发好的底层平台&#xff0c;开发上层应用的常用方法。下面对回调函数做一个详细的解释。 目录 1. 简单的回调函数实例 2. C11&#xff0c;使用function<>的写法 3. 注册函数 …...

<电力行业> - 《第8课:输电(一)》

1 输电环节的意义 电能的传输&#xff0c;是电力系统整体功能的重要组成环节。发电厂与电力负荷中心通常都位于不同地区。在水力、煤炭等一次能源资源条件适宜的地点建立发电厂&#xff0c;通过输电可以将电能输送到远离发电厂的负荷中心&#xff0c;使电能的开发和利用超越地…...

【python学习】 __pycache__ 文件是什么

__pycache__文件是Python中的一个特殊目录&#xff0c;主要用于存储已编译的字节码文件&#xff08;.pyc文件&#xff09;。以下是关于__pycache__文件的详细解释&#xff1a; 作用&#xff1a;当Python解释器执行一个模块时&#xff0c;它会首先检查是否存在对应的.pyc文件。…...

论文阅读_基本于文本嵌入的信息提取

英文名&#xff1a;Embedding-based Retrieval with LLM for Effective Agriculture Information Extracting from Unstructured Data 中文名&#xff1a;基于嵌入的检索&#xff0c;LLM 从非结构化数据中提取有效的农业信息 地址: https://arxiv.org/abs/2308.03107 时间&…...

kafka学习笔记08

Springboot项目整合spring-kafka依赖包配置 有这种方式&#xff0c;就是可以是把之前test里的配置在这写上&#xff0c;用Bean注解上。 现在来介绍第二种方式&#xff1a; 1.添加kafka依赖&#xff1a; 2.添加kafka配置方式: 编写代码发送消息&#xff1a; 测试&#xff1a; …...

Flask的 preprocess_request

理解 Flask 类似框架中的 preprocess_request 方法 在 Flask 类似的 web 框架中&#xff0c;preprocess_request 方法是一个关键组件。它在请求被分派之前调用&#xff0c;用于执行一些预处理操作。让我们一步一步来理解这个方法的工作原理。 1. 方法概述 首先&#xff0c;我…...

重温react-05(类组件生命周期和性能优化)

类组件的生命周期 import React, { Component } from reactexport default class learnReact05 extends Component {state {number: 1}render() {return (<div>{this.state.number}</div>)}// 一般将请求的方法,放在这个生命周期componentDidMount() {setInterva…...

RHCE四---web服务器的高级优化方案

一、Web服务器&#xff08;2&#xff09; 基于https协议的静态网站 概念解释 HTTPS&#xff08;全称&#xff1a;Hyper Text Transfer Protocol over Secure Socket Layer 或 Hypertext TransferProtocol Secure&#xff0c;超文本传输安全协议&#xff09;&#xff0c;是以…...

Pytest集成Allure生成测试报告

# 运行并输出报告在Report文件夹下 查看生成的allure报告 1. 生成allure报告&#xff1a;pycharm terminal中输入命令&#xff1a;产生报告文件夹 pytest -s --alluredir../report 2. pycharm terminal中输入命令&#xff1a;查看生成的allure报告 allure serve ../report …...

SpringBoot 参数校验

参数校验 引入springvalidation依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId> </dependency>参数前添加Pattern public Result registry(Pattern(regexp &qu…...

【Arduino】实验使用ESP32控制可编程继电器制作跑马灯(图文)

今天小飞鱼实验使用ESP控制继电器&#xff0c;为了更好的掌握继电器的使用方法这里实验做了一个跑马灯的效果。 这里用到的可编程继电器&#xff0c;起始原理并不复杂&#xff0c;同样需要ESP32控制针脚输出高电平或低电平给到继电器&#xff0c;继电器使用这个信号控制一个电…...

islower()方法——判断字符串是否全由小写字母组成

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 语法参考 islower()方法用于判断字符串是否由小写字母组成。islower()方法的语法格式如下&#xff1a; str.islower() 如果字符串中包含至少一个区…...

发布/订阅模式

实现发布/订阅模式的基本思路是通过一个中介者&#xff08;发布者&#xff09;来管理订阅者&#xff08;监听器&#xff09;&#xff0c;并在特定事件发生时通知所有订阅者执行相应的操作。下面是实现发布/订阅模式的基本思路&#xff1a; 创建发布者对象&#xff1a;首先&…...

K8S Pod常见状态

这是自己所遇到 Pod 常见状态及可能原因&#xff0c;持续更新。 如有其他的错误状态&#xff0c;可私我更新 1. ImagePullBackOff 问题分析&#xff1a; 镜像拉取失败。 可能原因&#xff1a; 可能是网络问题导致&#xff0c;检查Pod所在节点是否能够正常访问网络; 镜…...

Hadoop3:Yarn常用Shell命令

一、查看任务 1、查看所有任务 yarn application -list2、根据状态查看任务 语法 yarn application -list -appStates &#xff08;所有状态&#xff1a;ALL、NEW、NEW_SAVING、SUBMITTED、ACCEPTED、RUNNING、FINISHED、FAILED、KILLED&#xff09;例如 yarn application…...

15.数据库简介+MySQl使用+SQL语句

文章目录 数据库简述一.数据库简介DB1.定义:2.DBMS数据库管理系统3.数据库分类 二.MySQL的安装1.安装步骤2.MySQL数据库图形管理工具3.mysql程序常用命令4.MySQL字符集及字符序5.Navicat快捷键操作 三.MySQL数据库基本操作 .........................................表管理一.…...

AI入门系列:工具篇之ChatGPT的优秀的国内替代品

文章目录 一&#xff0c;智谱清言(ChatGLM)1&#xff0c;智谱清言简介2&#xff0c;[智谱清言地址&#xff0c;点我开始用吧](https://chatglm.cn/) 二&#xff0c;Kimi智能助手1&#xff0c;Kimi简介2&#xff0c;[Kimi地址&#xff0c;点我开始用吧](https://kimi.moonshot.c…...

改机软件有哪些?实现一键新机、改串号、改IMEI和手机参数的需求 硬改手机软件,新机环境模拟 设备伪装,一键改机,一键复原

这次针对可以直接开端口修改参数的机型做一些工具解析 前面接触合作过很多工作室。其中很多工作室对于各自软件的跳验证有各自的需求。 一个机型各项参数一般有IMEI WiFi 蓝牙 sn psb ESN等等。 针对这些参数的修改首先要明白各自软件检测的具体是哪些参数来验证。 对于常用…...

如何快速使用JNI

文章目录 1_JNI是什么&#xff1f;2_使用3_扩展 1_JNI是什么&#xff1f; JNI 是Java Native Interface的缩写&#xff0c;通过JNI&#xff0c;允许Java代码与其他语言&#xff08;通常是C或C&#xff09;编写的本地应用程序或库进行交互。简而言之就是&#xff0c;Java可以通…...

simulink开发stm32,使用中断模块,无法产生中断,其中包括使用timer模块,以及ADC都无法产生中断,需要注意的地方

1&#xff0c;其中包括使用timer模块&#xff0c;以及ADC都无法产生中断&#xff0c;需要注意的地方 原来是需要在配置文件里开启一下timer的中断&#xff0c;其他模块自动加载ioc就可以了&#xff0c;这个timer需要注意力&#xff0c;需要自己勾选一下 如下图&#xff1a; 看…...

C# 如何单纯的优化循环

Parallel.For(0, 10000, i >{// 并行执行的代码块// 例如: Console.WriteLine(i);}); 这种循环比 单纯常用的for 和 foreach 要稍微快一点 但是呢如果循环里面写的是非常简单的业务逻辑 的话 for和foreach 要更胜一筹一点 Parallel 原理就好像我一个人忙不过来可以多找几个…...

【鸿蒙学习笔记】@Extend装饰器:定义扩展组件样式

官方文档&#xff1a;Extend装饰器&#xff1a;定义扩展组件样式 [Q&A] Extend装饰器 作用 Extend用于扩展原生组件样式。 [Q&A] Extend装饰器 特点 &#xff11;・Extend仅支持在全局定义&#xff0c;不支持在组件内部定义。 &#xff12;・Extend支持封装指定组件的…...

【Docker项目实战篇】Docker部署PDF多功能工具Stirling-PDF

【Docker项目实战篇】Docker部署PDF多功能工具Stirling-PDF 前言一、Stirling-PDF介绍1.1 Stirling-PDF简介1.2 Stirling-PDF功能 二、本次实践规划2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四…...

【算法训练记录——Day37】

Day37——贪心Ⅴ 1.leetcode_56合并区间 1.leetcode_56合并区间 思路&#xff1a;排序&#xff0c;如果重叠&#xff0c;更新right 为max(right, curVal), 不重叠就加入res,需要单独考虑最后一次&#xff0c;因为每次都是在下一次遍历开始时判断是否加入res&#xff0c;因此 当…...

OpenCV 张正友标定法(二)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 在之前的博客OpenCV 张氏标定法中,我们没有考虑镜头畸变等因素,因此计算出的内参与外参均是理想情况下的数值,而如果我们考虑到镜头的畸变: 我们就需要考虑使用最小二乘法最小化像素坐标的重投影误差(上述所求…...

LeetCode题练习与总结:环形链表Ⅱ--142

一、题目描述 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测…...

【kaptcha】kaptcha验证码的使用-SpringBoot集成

Kaptcha验证码的依赖 <dependency><groupId>com.github.penggle</groupId><artifactId>kaptcha</artifactId><version>2.3.2</version> </dependency> Kaptcha验证码的配置类&#xff0c;对验证码的一些属性进行配置&#x…...

golang template模板嵌套语法 为何不能使用变量 底层源码解析

我们都知道在golang的模板语法中&#xff0c;我们可以使用template关键字嵌套其他模块&#xff0c; 如&#xff1a; {{template "模板文件名" .}} 然而&#xff0c;这里的 “模板文件名” 是不能使用变量的&#xff01; 注意这里最后的的 . 这个实际上是templa…...

【Linux】线程Thread

&#x1f525;博客主页&#xff1a; 我要成为C领域大神&#x1f3a5;系列专栏&#xff1a;【C核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 本博客致力于知识分享&#xff0c;与更多的人进行学习交流 ​ ​ 线程概述 …...

RAG技术:在自然语言处理中的深度融合与创新

在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;随着技术的不断进步&#xff0c;我们见证了各种创新方法的涌现。其中&#xff0c;检索增强生成&#xff08;Retrieval-Augmented Generation&#xff0c;简称RAG&#xff09;技术以其独特的优势&#xff0c;逐渐成为…...

什么是std::bind

2024年6月29日&#xff0c;周日下午 std::bind 是一个C11标准库中的函数&#xff0c;它用于将一个函数或函数对象与特定的参数绑定在一起&#xff0c;生成一个新的函数对象。 std::bind通常和std::function一起使用&#xff0c;因为std::function可以作为一个函数容器来接收st…...

C语言的数据结构:树与二叉树(哈夫曼树篇)

前言 上篇讲完了二叉树&#xff0c;二叉树的查找性能要比树好很多&#xff0c;如平衡二叉树保证左右两边节点层级相差不会大于1&#xff0c;其查找的时间复杂度仅为 l o g 2 n log_2n log2​n&#xff0c;在两边层级相同时&#xff0c;其查找速度接近于二分查找。1w条数据&am…...

docker 安装syslog

Syslog-ng是一个可靠、多功能的日志管理系统&#xff0c;用于收集日志并将其转发到指定的日志分析工具。 使用Docker CLI方式搭建 步骤 1: 拉取Syslog-ng镜像 首先&#xff0c;需要从Docker Hub拉取Syslog-ng的官方镜像。 docker pull balabit/syslog-ng:latest 步骤 2: 启动…...

什么是无头浏览器?

简而言之&#xff0c;无头浏览器是没有图形用户界面 &#xff08;GUI&#xff09; 的 Web 浏览器。GUI 包括用户与之交互的数字元素&#xff0c;例如按钮、图标和窗口。但是&#xff0c;关于无头浏览器&#xff0c;您需要了解的还有很多。 在本文中&#xff0c;您将了解什么是…...

【面试干货】与的区别:位运算符与逻辑运算符的深入探讨

【面试干货】&与&&的区别&#xff1a;位运算符与逻辑运算符的深入探讨 1、&&#xff1a;位运算符2、&&&#xff1a;逻辑运算符3、&与&&的区别 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; & 和 …...

搭建Renesas R7FA8D1BHECBD-BTB的开发调试环境(DAP-LINK: N32G45XVL-STB)

目录 概述 1 软硬件 1.1 软硬件环境信息 1.2 开发板信息 1.3 调试器信息 2 FSP和KEIL产生测试项目 2.1 FSP生成项目 2.2 Keil中配置 3 硬件连接框图 4 一个测试案例 4.1 功能介绍 4.2 定时器函数 5 测试 搭建Renesas R7FA8D1BHECBD-BTB的开发调试环境&#xff08…...

探索人工智能和LLM对未来就业的影响

近年来&#xff0c;人工智能&#xff08;AI&#xff09;迅猛发展&#xff0c;引发了人们的兴奋&#xff0c;同时也引发了人们对就业未来的担忧。大型语言模型&#xff08;LLM&#xff09;就是最新的例子。这些强大的人工智能子集经过大量文本数据的训练&#xff0c;以理解和生成…...

钓鱼网站原理与攻防

知识点&#xff1a;LAMP平台部署&#xff0c;Web架构分析&#xff0c;钓鱼网站原理与搭建 中间件&#xff1a; 中间件是一种独立的软件&#xff0c;位于客户机和服务器之间&#xff0c;主要用于在网络环境中进行数据的传输和通信。它充当客户端和服务端之间的桥梁&#xff0c;…...

Windows 中 Chrome / Edge / Firefox 浏览器书签文件默认存储路径

1. Chrome 浏览器 按组合键 Win R&#xff0c;打开运行对话框&#xff0c;输入 %USERPROFILE%\AppData\Local\Google\Chrome\User Data\Default或在Chrome 浏览器地址栏输入 chrome://version查看【个人资料路径】 2. Edge 浏览器 按组合键 Win R&#xff0c;打开运行对…...

秋招Java后端开发冲刺——关系型数据库篇(Mysql)

本文介绍关系型数据库及其代表Mysql数据库&#xff0c;并介常见面试题目。 一、数据库概述 1. 数据库&#xff08;Database, DB&#xff09;&#xff1a;是长期储存在计算机内的、有组织的、可共享的数据集合。 2. 数据库管理系统&#xff08;Database Management System, D…...

DHCP原理1-单个局域网出现多个DHCP服务器会发生什么

1. 背景 DHCP全称是Dynamic Host Configuration Protocol。其协议标准是RFC1541&#xff08;已被RFC2131取代&#xff09;&#xff0c;主要实现服务器向客户端动态分配IP地址&#xff08;如IP地址、子网掩码、网关、DNS&#xff09;和配置信息。其系统架构是标准的C/S架构。RFC…...

24/06/29(21.1205)程序的编译和链接

源文件 ---> 可执行文件,这一过程要执行的流程: 预处理 编译 汇编 链接 组成每一个程序的每个源文件通过编译过程分别转换成目标代码;每个目标代码由链接器捆绑在一起,形成一个单一而完整的可执行程序;链接器同时也会引入标准函数库中任何被该程序所用到的函数,而且它可以…...

RpcChannel的调用过程

目录 1. RPC调用方&#xff08;caller&#xff09;的调用(消费)过程 2.在caller下创建文件&#xff1a;calluserservice.cc 3.在src的include下创建文件&#xff1a;mprpcchannel.h 4.在src下创建mprpcchannel.cc 1. RPC调用方&#xff08;caller&#xff09;的调用(消费)过…...

简单的手动实现spring中的自动装配案例

简简单单的实现一个spring中的自动装配和容器管理的小骚操作。 1&#xff0c;创建AutoSetBean.java 使用injectBeans静态方法&#xff0c;可以扫描指定包下的所有带MyInject注解的字段&#xff0c;如果在beans的Map中存在这个字段的实例化类&#xff0c;则执行装配。 import…...

第4-5天:30余种加密编码和资产架构端口应用CDNWAF站库分离负载均衡

文章目录 前言知识点常见加密编码等算法解析 资产架构&端口&应用&CDN&WAF&站库分离&负载均衡资产架构番外安全考虑阻碍 前言 在安全测试中常见的敏感信息密码等会采用加密方式&#xff0c;因此作为一名安全人员要了解常见加密。 知识点 主要有存储加…...

自动驾驶AVM环视算法--相机的联合标定算法实现和exe测试demo

更新&#xff1a;测试的exe程序&#xff0c;无需解压码就可以体验算法测试效果 链接&#xff1a;https://pan.baidu.com/s/1OfuslVNcTXAZWvwiqflWsA 提取码&#xff1a;zoef 1、压缩包解压后显示如下所示 测试文件包括&#xff1a;可执行的exe文件、测试的图片等。 2.双击ex…...

虚拟机交叉编译基于ARM平台的opencv(ffmpeg/x264)

背景&#xff1a; 由于手上有一块rk3568的开发板&#xff0c;需要运行yolov5跑深度学习模型&#xff0c;但是原有的opencv不能对x264格式的视频进行解码&#xff0c;这里就需要将ffmpegx264编译进opencv。 但是开发板算力有限&#xff0c;所以这里采用在windows下&#xff0c;安…...

基于Qt实现的PDF阅读、编辑工具

记录一下实现pdf工具功能 语言&#xff1a;c、qt IDE&#xff1a;vs2017 环境&#xff1a;win10 一、功能演示&#xff1a; 二、功能介绍&#xff1a; 1.基于saribbon主体界面框架&#xff0c;该框架主要是为了实现类似word导航项 2.加载PDF放大缩小以及预览功能 3.pdf页面跳转…...

中信建投证券06066:“21信投10”将于7月12日本息兑付并摘牌

智通财经APP讯,中信建投证券发布公告,2021年面向专业投资者公开发行次级债券(第五期)(品种二)(以下简称“本期债券”),将于2024年7月12日开始支付自2023年7月12日至2024年7月11日期间的利息和本期债券本金。据悉,本期债券简称“21信投10”,发行总额1亿元,债券期限为3年,…...

飞凡第三款车定名RC7:比理想L6好看,还比它便宜?

“今年年中,飞凡汽车全新的重磅车型将与广大用户见面,敬请期待。”这是今年年初,飞凡汽车在一封致合作伙伴的公开信中披露的内容。不料想时间刚刚来到5月中旬,飞凡就马不停蹄兑现了自己的诺言,将品牌第三款车型带到了工信部新车公示目录。根据公开信息显示,飞凡第三款车型…...

起售13.98万,取消鲢鱼嘴设计,试驾体验第十一代索纳塔!

对于2002年就进入国内市场的索纳塔,相信大多数人并不陌生,定位上是一台中型车,整体的风格就是突出运动基因,而在今年是迎来了家族第十一代车型上市。车辆指导售价在13.98~18.68万之间,作为一台中型车,定价方面还算合理,从低到高,动力上有两种选择,一种是1.5T涡轮增压引…...

JRT性能演示

演示视频 君生我未生&#xff0c;我生君已老&#xff0c;这里是java信创频道JRT&#xff0c;真信创-不糊弄。 基础架构决定上层建筑&#xff0c;和给有些品种的植物种植一样&#xff0c;品种不对&#xff0c;施肥浇水再多&#xff0c;也是不可能长成参天大树的。JRT吸收了各方…...

FPGA——eMMC验证

一.FPGA基础 1.FPGA烧录流程 (1) 加载流文件 —— bitfile (2) 烧录文件 —— cmm 二.MMC 1.基础知识 (1)jz4740、mmc、emmc、sd之间的关系&#xff1f; jz4740——处理器 mmc——存储卡标准 emmc——mmc基础上发展的高效存储解决方案 sd—— 三.eMMC和SD case验证 1.ca…...

【UnityShader入门精要学习笔记】第十五章 使用噪声

本系列为作者学习UnityShader入门精要而作的笔记&#xff0c;内容将包括&#xff1a; 书本中句子照抄 个人批注项目源码一堆新手会犯的错误潜在的太监断更&#xff0c;有始无终 我的GitHub仓库 总之适用于同样开始学习Shader的同学们进行有取舍的参考。 文章目录 使用噪声上…...